2010-12-02 23 views
0

J'essaie de comprendre la syntaxe incroyablement confuse de RSpec, au moins au début, en essayant de développer les spécifications par défaut qui sont générées avec l'échafaudage Rails 3 ...RSpec stubs & mocks sur les relations connexes (belongs_to)

j'ai modèles associés ... très simplement:

#clown.rb 
class Clown < ActiveRecord::Base 
    has_many :rabbits 
end 

#rabbit.rb 
class Rabbit < ActiveRecord::Base 
    belongs_to :clown 
end 

mais j'ai des problèmes avec rabbits_controller.spec.rb. En ce que les spécifications échouent quand je fais référence, disons, au clown. nom dans l'une des vues de lapin. l'application simple stupide fonctionne comme prévu mais les spécifications échouent parce que je n'ai pas écrasé (ou moqué?) le clown pour répondre correctement du lapin (ou du moins c'est ce que je pense qui se passe)?!? Comment devrais-je ajouter un bout (ou se moquer du clown auquel le lapin est associé?).

existant:

#rabbits.controller.spec.rb 
    require 'spec_helper' 

    describe RabbitsController do 

     def mock_rabbit(stubs={}) 
     (@mock_rabbit ||= mock_model(Rabbit).as_null_object).tap do |rabbit| 
      rabbit.stub(stubs) unless stubs.empty? 
     end 
     end 

     describe "GET index" do 
     it "assigns all rabbits as @rabbits" do 
      Rabbit.stub(:all) { [mock_rabbit] } 
      get :index 
      assigns(:rabbits).should eq([mock_rabbit]) 
     end 
     end 

    ... 

Répondre

1

à mon humble avis (et il y a d'autres points de vue), ce n'est pas une situation ou moqueur stubbing. Les mocks et les stubs sont parfaits pour les dépendances externes (pensez au service web), mais ceci est interne à votre application. Ce que vous voulez est quelque chose comme factory_girl, qui vous permettra de créer des données de test sans les maux de tête de quelque chose comme des appareils ou d'essayer de se moquer de chaque relation dépendante, qui devient rapidement monotone. factory_girl a une grande documentation, mais brièvement voici ce que vos usines pourraient ressembler à:

Factory.define(:clown) do |f| 
    f.rabbits{|c| [c.assocation(:rabbit)]} 
    f.name "Pierrot" 
end 

Factory.define(:rabbit) do |f| 
    f.association :clown 
end 

Vous souhaitez ensuite les utiliser dans votre test comme ceci:

describe RabbitsController do 
    describe "GET index" do 
    it "assigns rabbits" do 
     @rabbit = Factory(:rabbit) 
     get :index 
     assigns[:rabbits].should == [@rabbit]  
    end 
    end 
end 
bien
+0

, cela devient plus confus à quelqu'un d'apprentissage .. pourquoi le modèle Rails3/RSpec inclue le bloc 'mock_rabbit' par défaut? Juste pour confondre les gens comme moi? Je découvre que plus j'en apprends sur Rails moins je le sais vraiment ... – Meltemi

+0

Je n'ai aucune idée :) Peut-être qu'ils ont des trucs que je ne connais pas, mais en tant que quelqu'un qui teste religieusement j'ai trouvé la vie beaucoup plus facile avec des usines pour mes dépendances internes. Pendant longtemps, il y avait beaucoup de gens qui réclamaient que vos tests restent indépendants d'une connexion à une base de données, mais je pense qu'au fil du temps, c'est comme un PITA et que vos tests deviennent plus axés sur les tests d'applications. – karmajunkie