2011-07-01 4 views
3

J'essaie de tester le modèle Hour avec RSpec, à savoir la méthode de classe 'find_days_with_no_hours' qui se comporte comme une portée. Les affaires ont beaucoup d'heures associées par STI. find_days_with_no_hours doit être appelé via un objet métier et je n'arrive pas à comprendre comment le configurer dans le test RSpec. Je veux être en mesure de tester quelque chose comme:Test has_many association avec RSpec

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

J'ai essayé différentes approches, comme la création d'un objet métier (avec, disons, Business.create), puis définir @ business.hours < < mock_model (BusinessHour, ..., ..., ...) mais ça ne marche pas.

Comment cela se fait-il normalement?

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 

Répondre

8

Vous ne pouvez pas tester une méthode arel en créant l'objet via des mock. Arel va directement dans la base de données, et ne voit pas de faux-semblants ou quoi que ce soit que vous ayez créé en mémoire. Je prends factory_girl puis définir une usine d'heure pour vous-même:

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

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

Et puis dans votre test ...

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

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

Cependant, factory_girl est juste une préférence personnelle pour la mise en place état connu, vous peut tout aussi facilement utiliser des instructions create ou des fixtures, le problème pour vous essayait d'utiliser mock_model() (qui empêche un hit de base de données), puis en utilisant une méthode qui interroge la base de données.