views:

98

answers:

1

Hi there,

I'm having a problem testing the following model:

class Bill < ActiveRecord::Base
  belongs_to :consignee
  before_save :calc_rate

  def calc_rate
    self.chargeableweight = self.consignee.destination.rate * self.weight
  end
end

The consignee model:

class Consignee < ActiveRecord::Base
  belongs_to :destination
  has_many :bills
end

The controllers are not touched yet.

The behavior of the app is correct (follow up question: are there any performance problems with that solution?) - but the the test break.

You have a nil object when you didn't expect it! You might have expected an instance of Array. The error occurred while evaluating nil.*

Thank you in advice, Danny

update:

This bill test breaks using factory girl:

describe Bill do

  it "should call the calc_rate method" do
    bill = Factory.build(:bill)
    bill.save!
    bill.should_receive(:calc_rate)
  end
end

You have a nil object when you didn't expect it!

Factories:

Factory.define :destination do |f|
  f.airport_code "JFK"
end

Factory.define :consignee do |f|
  ...
  f.association :destination
end


Factory.define :bill do |f|
  f.association :consignee
  f.weight 10
  f.chargeableweight 20.0
  f.after_create do |bill|
    bill.calc_rate
end
+1  A: 
describe Consignee do
  it "should calculate the rate" do
    #pending
    #make sure this spec is passing first, so you know your calc_rate method is fine.
  end

  it "should accept calc_rate before save" do
    cosignee = mock("Consignee")
    consignee.should_receive(:calc_rate).and_return(2) # => stubbing your value
  end
end

I didn't spool up a rails app to test this code, but this should get you close. also, assuming that the columns chargeable_rate, weight, etc are columns on the model, you dont need to call self. Ruby will implicitly expect self if there is no instance method or variable of that name available it will automatically look for class methods.

Jed Schneider
Thanks for your quick answer Jed.Sorry for being unclear.I changed the question - see above
Daniel Ozean
your destination factory is expecting the method rate, but this is not defined in your factory for destination. thats at least one problem i see. without a stack trace its hard to know where it is calling nil.
Jed Schneider
Thanks Jed, you are right.The missing rate in the factory was the problem ...
Daniel Ozean
thanks, and welcome. please mark as answered and good luck.
Jed Schneider