À quoi sert Verifiable () dans Moq?

125

Quel est le but de Verifiable()?

Si je vérifie un Mocket que je laisse ceci de côté, il vérifie toujours le SetUp.

Edit: J'utilisais VerifyAll()ainsi la raison pour laquelle tout était vérifié. Après avoir changé pour Verify()seulement mes .Verifiable() SetUps ont été vérifiés.

Castrohenge
la source

Réponses:

83

ADDENDUM: Comme l'indique l'autre réponse, le but de .Verifiableest d'enrôler un Setupdans un ensemble "d' Verify(...)appels différés " qui peuvent ensuite être déclenchés via mock.Verify().

La clarification de l'OP indique clairement que c'était l'objectif et que le seul problème était de comprendre pourquoi cela ne fonctionnait pas, mais comme @Liam l'a poussé, la réponse devrait vraiment toucher à cela aussi: - Les cas d'utilisation clés dans la mesure où je peux voir sont:

  • le maintien de la SECHÉ entre a mock.Setup()etmock.Verify
  • permettant de déconnecter la configuration d'une vérification de l' Verifyappel lui-même (par exemple, vous pouvez le configurer dans une autre méthode d'assistance)

... et revenons à ma réponse, qui dit de manière laconique et efficace: "soyez prudent car les avantages ci-dessus sont généralement considérés comme compensés par l'effet que la réalisation de ces objectifs a sur la lisibilité et la maintenabilité des tests qui s'appuient trop sur de telles constructions"

ORIGINAL: Notez que lorsque cela est possible, il faut plutôt suivre la disposition AAA et par conséquent, il faut faire des mock.Verify( expression )appels explicites après que le travail a été fait, plutôt que mock.Setup( ... ).Verifiable()jumelé avec un mock.Verify()oumock.VerifyAll() lorsque cela est possible (crédit: @kzu ).

Ruben Bartelink
la source
7
@EricSmith Avec le recul, je ne pense pas que je le dise assez fortement. Il y a beaucoup plus d'avantages à diviser votre travail en regroupement AAA qu'à une concentration excessive sur les points communs entre la phase d'arrangement et d'assertion. 90% du temps, il y a quelque chose à gagner dans les nuances de la façon dont vous exprimez les appels de vérification à la fin, vous devriez donc prendre beaucoup de temps pour optimiser pour cela, même si dans certains cas, cela semble être une duplication douloureuse. L'un des points que manning.com/osherove fait très bien est qu'il est essentiel de donner un sens à un test pour quelqu'un qui saute, alors respectez les conventions!
Ruben Bartelink
3
Je ne suis normalement pas du genre à aller à l'encontre du sens de la sagesse acceptée, mais je ne suis pas encore convaincu des avantages de l'AAA par rapport à Verifyable()/ VerifyAll()dans tous les cas. Mon test unitaire actuel comporte un grand nombre d' Setup(...)appels (> 30). Pourrait faire correspondre chacun d'eux avec un Verify () équivalent pour satisfaire la convention, mais cela entraîne une grande quantité de duplication de code et sera plus difficile à maintenir et à lire à mesure que le nombre de tests unitaires augmente. Je suppose que ce que je demande vraiment, c'est peut-on faire des exceptions s'il y a un grand nombre de configurations ou est-ce que l'on évite Verifiable()une règle dure et rapide?
Steve Chambers
5
@SteveChambers Un élément clé d'AAA est que ce n'est pas A * - il devrait y avoir un seul Acte et une seule Assert. Donc, bien que vous ayez techniquement raison de dire que c'est moins de code pour vous, les coïncidences de laquelle de vos configurations s'applique à quels (sous) actes et (sous) assertions deviendra invariablement un champ de mines. Donc non, ce n'est pas difficile et rapide, mais je dirais que suggérer que c'est même proche de 50:50 serait un très mauvais conseil. (Notez également que vous n'avez pas besoin de faire une configuration pour faire une vérification à moins que vous n'essayiez d'introduire un comportement particulier pendant l'acte - qui est encore un autre élément de tests clairs)
Ruben Bartelink
1
@Liam Et il est en effet tout à fait bien que vous êtes toujours convaincu qu'il est un outil approprié pour votre travail - mon vrai problème est juste qu'il est mal vu comme une approche générale à l' écriture des tests avec simulacres - dire en dépit du fait qu'il réalise parfaitement sec entre a Setupet a Verify, qui peut manquer une victoire plus élevée réalisable, il suffit de relâcher la contrainte DRY de la manière suggérée par AAA et la famille de stratégies qui l'implique fortement
Ruben Bartelink
1
@Liam Merci pour la sollicitation; J'ai mis à jour ma réponse parce que vous avez raison dans ce que vous faites. À l'époque où je répondais à des questions SO comme celle-ci, mon point de vue était généralement d'énoncer succinctement une réponse atomique, puis de laisser des réponses concurrentes comme les autres remplir la carte. Ces jours-ci (si je prenais encore le temps de répondre aux questions), j'essaierais probablement de donner la réponse la plus complète que cela est devenue en premier lieu.
Ruben Bartelink
54

Lorsque la Verify()méthode est appelée à la fin du test, si l'une des attentes marquées comme vérifiables n'a pas été appelée, alors une exception est thrown.

VerifyAll() ne vérifie pas les attentes vérifiables.

Suvesh Pratapa
la source
Pourriez-vous expliquer un peu plus sur VerifyAll () ne vérifie pas les attentes vérifiables?
JW
@JW Cela signifie que VerifyAll vérifie toutes les configurations sans considérer si elles ont été marquées comme des attentes vérifiables.
phoog