测试has_many与RSpec的关联

我正在尝试使用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  :hourable end class Hour  true def self.find_days_with_no_hours where("start_time IS NULL") end end 

您无法通过模拟创建对象来测试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语句或fixtures,你的问题是尝试使用mock_model()(这会阻止数据库命中),然后使用一个方法查询数据库。