如何测试before_save方法,包括与rspec的对比

时间:2010-08-08 11:16:28

标签: ruby-on-rails ruby unit-testing rspec

我在测试以下型号时遇到问题:

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

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

收货人模型:

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

尚未触及控制器。

应用程序的行为是正确的(跟进问题:该解决方案是否有任何性能问题?) - 但测试中断。

  

当你没有时,你有一个零对象   期待它!你可能已经预料到了   数组的实例。发生错误   在评估nil。*

谢谢你的建议, 丹尼

更新

这项法案测试使用工厂女孩打破:

describe Bill do

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

当你没想到它时,你有一个零对象!

工厂:

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 个答案:

答案 0 :(得分:1)

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

我没有使用rails应用来测试此代码,但这应该会让你接近。另外,假设列chargeable_rate,weight等是模型上的列,你不需要调用self。如果没有该名称的实例方法或变量,Ruby将隐式地期望self,它将自动查找类方法。