测试has_many与RSpec的关联

时间:2011-07-01 20:04:11

标签: ruby-on-rails ruby-on-rails-3 rspec rspec-rails

我正在尝试使用RSpec测试Hour模型,即类似于作用域的类方法'find_days_with_no_hours'。业务有多个与STI相关的营业时间。 需要通过Business对象调用find_days_with_no_hours,我无法弄清楚如何在RSpec测试中设置它。 我希望能够测试类似的东西:

bh = @business.hours.find_days_with_no_hours
bh.length.should == 2

我尝试了各种方法,比如创建一个Business对象(比如Business.create),然后设置@ business.hours<< mock_model(BusinessHour,...,...,...)但这不起作用。

这通常是怎么做的?

class Business < ActiveRecord::Base

  has_many :hours, :as => :hourable

end

class Hour < ActiveRecord::Base

  belongs_to :hourable, :polymorphic => true

  def self.find_days_with_no_hours
    where("start_time IS NULL")
  end

end

1 个答案:

答案 0 :(得分:8)

您无法通过模拟创建对象来测试arel方法。 Arel将直接进入数据库,而不会看到任何模拟或您在内存中创建的任何内容。我会抓住factory_girl,然后为自己定义一个小时工厂:

Factory.define :hour do |f|
  f.start_time {Time.now}
end

Factory.define :unstarted_day, :parent => :hour do |f|
  f.start_time nil
end

然后在你的测试中...

business = Factory.create(:business)
business.hours << Factory.create(:unstarted_day)

bh = business.hours.find_days_with_no_hours
bh.length.should == 1

但是,factory_girl只是设置已知状态的个人偏好,您可以轻松使用create语句或装置,问题是您尝试使用mock_model()(这会阻止数据库命中) ,然后使用查询数据库的方法。