Testing has_many association with RSpec

蹲街弑〆低调 提交于 2019-12-10 17:55:01

问题


I'm trying to test the Hour model with RSpec, namely the class method 'find_days_with_no_hours' that behaves like a scope. Business has_many Hours associated through STI. find_days_with_no_hours needs to be called through a Business object and I can't figure out how to set this up in the RSpec test. I want to be able to test something like:

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

I've tried various approaches, like creating a Business object (with, say, Business.create), then setting @business.hours << mock_model(BusinessHour, ..., ..., ...) but that doesn't work.

How is this normally done?

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:


You can't test an arel method by creating the object via mocks. Arel is going to go straight into the database, and not see any mocks or anything that you've created in memory. I would grab factory_girl and then define an hour factory for yourself:

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

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

And then in your test...

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

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

However, factory_girl is just a personal preference for setting up known state, you can just as easily use create statements or fixtures, the problem for you was trying to use mock_model() (which prevents a database hit), and then using a method that queries the database.



来源:https://stackoverflow.com/questions/6552721/testing-has-many-association-with-rspec

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!