测试has_many与RSpec的关联

99m*_*les 3 rspec ruby-on-rails rspec-rails ruby-on-rails-3

我正在尝试使用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
Run Code Online (Sandbox Code Playgroud)

我尝试了各种方法,比如创建一个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
Run Code Online (Sandbox Code Playgroud)

nzi*_*nab 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
Run Code Online (Sandbox Code Playgroud)

然后在你的测试中......

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

bh = business.hours.find_days_with_no_hours
bh.length.should == 1
Run Code Online (Sandbox Code Playgroud)

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