2013-01-01 4 views
2

mon code modèle est:talon créant pour after_create crochet dans rspec

class User < ActiveRecord::Base 
    after_create :create_node_for_user 

    def create_node_for_user 
    UserGraph.create(user_id: self.id) 
    end 
end 

et un test pour le modèle de l'utilisateur:

it "create node in graph database on user creation" do 
    userr = FactoryGirl.build(:user) 
    UserGraph.should_receive(:create).with(user_id: userr.id) 
    userr.save 
end 

mais mon test est échoue avec un message

Failure/Error: userr.save 
    <UserGraph (class)> received :create with unexpected arguments 
    expected: ({:user_id=>nil}) 
      got: ({:user_id=>94}) 

ce peut-être tort?

+0

Quelque chose s'est-il connecté? –

Répondre

2

Le problème est que le userr que vous construisez avec FactoryGirl n'a pas d'ID. C'est pourquoi l'attente vous indique que vous attendiez :user_id=>nil. L'ID sera généré lorsque AR enregistre l'enregistrement, il est donc impossible de deviner l'ID généré à l'avance. Vous pouvez utiliser une affirmation moins restrictive sur la maquette:

UserGraph.should_receive(:create).with(hash_including(:user_id)) 

Ceci permettra de vérifier qu'un hachage est passé avec une clé :user_id. Vous pouvez trouver plus sur hash_including ici: http://rubydoc.info/gems/rspec-mocks/RSpec/Mocks/ArgumentMatchers:hash_including

Une autre chose que vous pouvez essayer (ne sais pas si cela fonctionne) est de faire correspondre kind_of matcher de rspec. Cela fait en sorte que plusieurs a été passé avec :user_id

UserGraph.should_receive(:create).with(:user_id => kind_of(Numeric)) 
3

L'explication donnée par Yves est correcte: l'ID utilisateur est nul jusqu'à ce que le dossier est enregistré parce qu'il est générée automatiquement par le DB. Voici une autre approche:

it "create node in graph database on user creation" do 
    userr = FactoryGirl.build(:user) 

    create_args = nil 
    UserGraph.should_receive(:create) { |*args| create_args = args } 
    userr.save 

    expect(create_args).to eq(:user_id => userr.id) 
end 

Essentiellement, cela déplace l'attente de ce que les arguments doivent être pour qu'il vienne après l'enregistrement a été enregistré, lorsque l'enregistrement a un id.

+0

pouvez-vous expliquer cette ligne 'UserGraph.should_receive (: create) {| * args | create_args = args} ' –

+0

Oui. Le bloc est un moyen de gérer le message 'create' avec du code arbitraire (voir https://github.com/rspec/rspec-mocks#arbitrary-handling). Quand 'UserGraph' reçoit le message' create', il va lancer le bloc fourni. Dans le bloc, je stocke les arguments fournis avec le message 'create' dans une variable locale afin que je puisse définir une attente plus tard, à la fin de l'exemple. –

Questions connexes