2017-10-18 20 views
0

Je voudrais vérifier si ma classe crée un nouvel objet et renvoie une instance de celui-ci. Mon idée était de combiner change matcher avec be_instance_of matcher mais RSpec ne permet pas de le faire.RSpec combiner le matcher de bloc avec matcher non-bloc

expect { subject.call }.to change { Model.count }.by(1).and be_an_instance_of(Model) 

Je ne veux pas le diviser en deux différents expects avec un sans bloc pour éviter de multiples invocations de la même méthode.

Quelle est l'approche générale de ce genre de situations? Comment dois-je gérer mon cas?

Répondre

1

Vous pouvez définir subject comme subject.call et faire:

specify do 
    expect { subject }.to change { Model.count }.by(1) 
    expect(subject).to be_an_instance_of(Model) 
end 

Donc, si auparavant votre sujet a été

subject { Foo.new } 

rendent

subject { Foo.new.call } 

let et subject appels sont memoized, il ne sera donc appelé qu'une seule fois.

Il y a un seul problème: si la première attente échoue - la seconde ne fonctionnera pas (et c'est SomethingToAvoidInSpecs ™) alors considérez aggregating failures pour y remédier.

+0

... Ou faites simplement deux tests, pas un. Si 'subject' n'est pas une opération coûteuse (lente), c'est la pratique normale. –

+0

Merci! Je n'ai pas pensé à le mettre dans le sujet. Passé plus d'une heure à essayer de le résoudre par la manière différente, mais il était si simple ... – Gregy

+0

@TomLord bien sûr on peut le faire, mais à partir de la question, j'ai eu l'impression qu'il veut l'éviter. – meta