Question

J'utilise NMock2, et je l'ai rédigé les classes de NMock suivantes pour représenter certains concepts cadre de simulation communs:

  • Expect: spécifie quelle méthode moquée doit revenir et dit que l'appel doit avoir lieu ou le test échoue (lorsqu'ils sont accompagnés par un appel à VerifyAllExpectationsHaveBeenMet())

  • .
  • Stub: spécifie quelle méthode moquée doit revenir mais ne peut pas faire un test à l'échec

  • .

Alors que dois-je faire?

Était-ce utile?

La solution

Beaucoup de cadres moqueurs apportent les concepts de simulacres et des talons plus et se rapprocher au point qu'ils peuvent être considérés comme fonctionnellement presque le même. Du point de vue conceptuel cependant, j'essaie généralement de suivre cette convention:

  • Mock :. Seulement lorsque vous essayez explicitement de vérifier le comportement de l'objet sous test (à savoir votre test dit que cet objet doit appeler cet objet)
  • Stub : Lorsque vous essayez de tester certaines fonctionnalités / comportement, mais afin d'obtenir que vous travailler besoin de compter sur des objets externes (votre test dit que cet objet doit faire quelque chose , mais comme un effet secondaire, il peut appeler cet objet)

Cela devient plus clair lorsque vous assurez-vous que chacun de vos tests unitaires seulement de test une chose. Bien sûr, si vous essayez de tester tout dans un seul test, alors vous pourriez aussi bien attendre à tout. Mais seulement attendre les choses que test unitaire spécifique pour la vérification, votre code est beaucoup plus claire parce que vous pouvez voir en un coup d'oeil quel est le but du test est.

Un autre avantage est que vous serez un peu plus isolés du changement et obtenir de meilleurs messages d'erreur lorsqu'un changement provoque une rupture. En d'autres termes, si vous changez subtley une partie de votre mise en œuvre, votre plus de chances d'obtenir une seule rupture de cas de test, qui va vous montrer exactement ce qui est cassé, plutôt que d'une série de tests tout casser et tout faire du bruit.

Modifier : Il pourrait être plus claire basée sur un exemple artificiel où un audit d'objets de calcul, tous les ajouts à une base de données (en pseudo-code) ...

public void CalculateShouldAddTwoNumbersCorrectly() {
    var auditDB = //Get mock object of Audit DB
    //Stub out the audit functionality...
    var calculator = new Calculator(auditDB);
    int result = calculator.Add(1, 2);
    //assert that result is 3
}

public void CalculateShouldAuditAddsToTheDatabase() {
    var auditDB = //Get mock object of Audit DB
    //Expect the audit functionality...
    var calculator = new Calculator(auditDB);
    int result = calculator.Add(1, 2);
    //verify that the audit was performed.
}

Ainsi, dans le premier cas de test, nous testons la fonctionnalité de la méthode Add et ne se soucient pas de savoir si un événement d'audit se produit ou non, mais il nous arrive de savoir que la calculatrice ne fonctionnera pas avec sur une référence auditDB si nous stub juste à nous donner le minimum de fonctionnalité pour obtenir notre cas de test spécifique de travail. Dans le second test, nous testons spécifiquement que lorsque vous faites un Add, l'événement d'audit arrive, donc ici, nous utilisons les attentes (avis que nous ne se soucient même pas ce que le résultat est, puisque ce n'est pas ce que nous faisons l'essai).

Oui, vous pouvez combiner les deux cas en un seul, et faire les attentes et affirmer que le résultat est 3, mais vous testez deux cas dans un test unitaire. Cela rendrait vos tests plus fragile (car il y a une plus grande surface des choses qui pourraient changer pour briser le test) et moins clair (puisque lorsque le test fusionné ne son que pas immédiatement évident que le problème est .. est l'ajout ne fonctionne pas, ou est l'audit ne fonctionne pas?)

Autres conseils

"Attendez-vous à des actions, des requêtes stub". Si l'appel doit changer l'état du monde extérieur l'objet sous test, puis faire une attente - vous vous souciez de la façon dont il est appelé. Si c'est juste une requête, vous pouvez l'appeler une ou six fois sans changer l'état du système, puis stub l'appel.

Une autre chose, notez que la distinction entre les talons et les attentes, que ce sont des appels individuels, pas nécessairement des objets entiers.

Eh bien ... à mon humble avis, il ne peut pas être plus simple: si votre test est de garantir votre présentateur STOCKER, n'Expect. si votre test consiste à assurer votre présentateur se chargera gracieusement exception si Save jette, livrez-vous Stub.

Pour plus de détails, consultez ce podcast par Hanselman et Osherove de (auteur de l'art de l'unité d'essai)

scroll top