43 votes

Est-il moins perturbateur pour de Rspec `should_receive`?

Dans l'écriture des tests Rspec, je suis souvent frustré should_receive. Je voudrais savoir si il y a un moins perturbateur.

Par exemple:

describe "making a cake" do
  it "should use some other methods" do
    @baker.should_receive(:make_batter)
    @baker.make_cake
  end
end

L'appel à l' should_receive est une bonne description, mais il casse mon code, car should_receive œuvres de masquage de la méthode originale, et make_cake ne peuvent se faire sans make_batter renvoie en fait certains de la pâte. J'ai donc changer à cela:

@baker.should_receive(:make_batter).and_return(@batter)

C'est moche parce que:

  • Il regarde comme je suis en essais qu' make_batter correctement les retours @batter, mais je me suis fait forcer la fausse version de l' make_batter de retour.
  • Il me force à créé séparément @batter
  • Si make_batter a des effets secondaires importants (qui peut être une odeur de code, je suppose), je dois faire ces se produire.

Je souhaite que should_receive(:make_batter) permettrait de vérifier l'appel de la méthode et de la transmettre à la méthode d'origine. Si je voulais stub son comportement pour une meilleure isolation de test, je le ferais de manière explicite: @baker.stub(:make_batter).and_return(@batter).

Est-il un moyen de faire quelque chose comme should_receive sans empêcher l'origine de l'appel de méthode? Est mon problème, un symptôme de la mauvaise conception?

63voto

Tyler Rick Points 3033

Il ressemble le plus beau de l'API de déléguer à la méthode originale que Myron Marston fait allusion a effectivement été ajouté dans rspec-se moque de v2.12.0

Alors maintenant, vous pouvez simplement le faire à tout moment vous "souhaitez définir un message expecation sans interférer avec la manière dont l'objet répond au message":

@baker.should_receive(:make_batter).and_call_original

Merci pour l'ajout de cette, Myron.

11voto

Myron Marston Points 8940

Vous pouvez avoir should_receive d'exécuter la méthode originale de la sorte:

@baker.should_receive(:make_batter, &@baker.method(:make_batter))

Les deux should_receive et stub charge la transmission d'un bloc de mise en œuvre (c'est-eval avais lorsque la méthode est appelée). &@baker.method(:make_batter) reçoit un manche à la méthode d'origine de l'objet, et passe ainsi que le bloc de mise en œuvre.

FWIW, nous aimerions offrir une belle API de déléguer à la méthode originale (voir ce numéro), mais il est difficile d'ajouter de nouvelles fonctionnalités sans casser la compatibilité ascendante.

6voto

Benedikt Deicke Points 499

Vous rencontrez ce problème avec should_receive parce que vous êtes à la mise en œuvre des tests de détails de l' make_cake méthode. Lors de l'écriture de tests que vous devriez se concentrer uniquement sur le comportement et non sur une séquence interne les appels de méthode. Sinon, la refactorisation de votre code plus tard, le résultat serait une énorme refonte de tous vos tests.

On se moque et les Talons sont très pratiques lorsque vous voulez tester vos classes dans l'isolement. Lors de l'écriture de tests unitaires votre sujet de test doit être isolé de tout autre objet. À la fois agir comme un stand-in lorsque vous travaillez avec plusieurs objets à la fois. Dans ce cas, vous pouvez utiliser should_receive pour vous assurer que votre sujet de test correctement délègue certaines tâches à un autre objet de l'appel d'une méthode.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X