Zollie Zollie - 1 month ago 8
Ruby Question

How to test class methods that rely on associations with RSpec and Sinatra?

I've written some RSpec tests that successfully create objects with :let statements. However, the test environment doesn't maintain the associations that function properly everywhere else. Below is an example of a class that would turn up a NoMethodError (undefined method `money' for nil:NilClass). Money is a column in Inventory. Any thoughts?

class Inventory < ActiveRecord::Base
belongs_to :character

def self.return_money(character)
character.inventory.money
end
end


And here's a corresponding example for a spec doc:

require 'spec_helper'

describe 'Test methods' do
let(:trader) {
Character.create(
name: "Trader",
location_id: 1)
}
let(:trader_inventory) {
Inventory.create(
character_id: trader.id,
storage_capacity: 50000,
money: 20000,
markup: 1.35)
}

it "test method" do
expect(Inventory.return_money(trader)).to eq(100)
end

end

Answer

There is no reason this shouldn't work. RSpec isn't special, it's just regular Ruby code. You can confirm this by moving all of your code into a single file, something like:

ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
ActiveRecord::Base.logger = Logger.new(STDOUT)

class Inventory < ActiveRecord::Base
end
class Character < ActiveRecord::Base
  has_one :inventory
end

describe 'test' do
  it 'works' do
    puts Character.first.inventory.money.inspect
  end
end

Guesses as to what may be broken:

  • money is a composite field or something like that. Can you post your database schema?
  • Library files aren't being loaded correctly. Use puts $LOADED_FEATURES to verify that all the files that should be required have been.