D'accord, cela pourrait être une question dangereuse à poser. Je fais des tests unitaires pendant un moment, mais pour une raison quelconque, je me suis réveillé ce matin et je me suis demandé cette question. p>
dise que j'ai une interface davessif, et il a la méthode CreateUser. p>
À un moment donné, j'ai besoin de créer un utilisateur? Je crée donc un test de vérification du test si CreateUser a été appelé à la facfice à l'endroit approprié. p>
Maintenant, les tests unitaires sont assez couplés au code réel - qui va bien. Mais peut-être un peu trop? Comme dans, le seul moyen de casser le test est de ne pas appeler l'appel à CreateUser. Nous ne vérifions pas sa mise en œuvre, etc. mais que vous venez de vérifier que l'interface a été appelée. Mais quiconque supprime cet appel aurait un test défaillant et supprimerait finalement la déclaration de vérification de l'étape pour vérifier que le CreateUser a été appelé. p>
J'ai vu cela arriver encore et encore. p>
Quelqu'un pourrait-il me ramener la lumière et expliquer pourquoi est-il bénéfique pour vérifier que les méthodes d'objets moquées ont été appelées? Je peux comprendre pourquoi il peut être utile de les définir, disons que CreateUser doit renvoyer un utilisateur factice pour une partie ultérieure du code, mais dans des endroits où nous sommes simplement et ne vérifient que s'ils ont été appelés, c'est la partie qui m'a été appelée. p>
Merci! P>
4 Réponses :
Non seulement Vérifiez-vous l'interface a été appelée, vous pouvez avoir plusieurs tests pour différents comportements de l'interface. Surtout les cas d'angle - Votre code a-t-il échoué avec gracieusement lorsque CreateUser renvoie une erreur Strike> soulève une exception? P>
Le seul moyen de casser le test est de ne pas appeler CreateUser P> blockQuote>
Donc, dans la méthode avec un peu de complexité, des conditionnels, etc., il pourrait être assez facile de sauter cet appel; La maintenance ultérieure pourrait entraîner involontairement l'appel à manquer. p>
Donc, je pense que ces tests d'effets secondaires peuvent avoir une valeur. Dans votre cas, le créateur devrait-il toujours être appelé? Qu'en est-il quand des exceptions sont jetées? Il peut y avoir des valeurs dans la vérification de ce que CreateUser est
pas forte> appelé dans certaines conditions. P> Je suis d'accord avec vous que, dans des situations simples, on entend parfois que nos tests et nos tests plus ou moins se répètent, et la maintenance devient un "code de changement de changement de changement d'esprit". Je pense que la valeur devient plus claire quand il y a plus de chemins et de manipulation d'erreurs. P>
Vérification d'un objet moqué est souvent un mal nécessaire et, comme vous l'avez mentionné, des tests unitaires sont parfois très étroitement couplés à la classe sous test.
Je ne sais pas comment donner une bonne réponse à votre question, mais Je vais essayer. P>
Prenez ce bit de code à titre d'exemple, où userpository est une dépendance (l'exemple n'est pas vraiment génial). P>
public void doSomething(User user) { if( user.isValid() ) { userRepository.save(user) } else { user.invalidate(); } }
Il est important de comprendre quelles sont les célébrations des objectifs servir dans le code testé: p>
DevisFactory code> exemple) LI>
- permet de déléguer le travail qui dépasse la portée de la classe, mais doit être fait (par exemple, une fonctionnalité de journalisation pourrait être une telle affaire) li>
ul>
Maintenant, si la dépendance (simulée) ne parvient pas à aider em>, de manière évidente du code qui dépend de cette aide échouera également. Dans de tels cas, avoir un test supplémentaire pour vérifier que la dépendance a été appelée, n'est pas très bénéfique. Aucun appel ne donnera à plusieurs échecs dans des tests qui en dépendent avec un message clair. P>
retour à votre exemple d'usine, que se passe-t-il quand il n'est pas appelé? Quelques autres tests, probablement ceux qui vérifient si cet utilisateur a été sauvé quelque part em>, ou que quelque chose a été fait avec celui-ci em> échouera. P>
Il y a naturellement un deuxième groupe de dépendances, ceux qui n'affectent pas du tout votre code, mais se produisent plutôt silencieusement en arrière-plan. Ceux-ci toutefois, ils seront très probablement reflétés dans vos responsabilités de code, disons: p>
Sauveduser La méthode doit enregistrer un nouvel utilisateur dans le référentiel et Résultat de l'opération de journal fort> p>
blockQuote>
généralement, il n'y a pas d'autre moyen de faire un contrôle de comportement que de vérifier si la méthode appropriée a été appelée. P>
En conclusion, deux questions à prendre en compte lors de la détermination de savoir si vous devriez écrire un test: p>
- Ce test vérifiera-t-il (une partie de) la responsabilité de ma classe? LI>
- Quelles connaissances sur le code testé vais-je gagner lorsque ce test passe / échoue? Li>
ul>
sauf si c'est nécessaire, ne testez pas que votre code appelle autrement d'autre code; Test que votre code fonctionne d'une manière que vous supposez qu'il fait strong>. P>
C'est une excellente question, je n'ai entendu parler que cette question de personnes qui sont vraiment en construction de code simple et de haute qualité. Je vous avez plus de questions comme celle-ci, merci de les partager!
merci @augusto! Certainement les partagera! :)
Les tests unitaires sont une double comptabilité. Nous équilibrons tout sur le côté gauche (code de production), avec tout sur le côté droit (tests), peu importe la simple semble-t-il. Cette pratique maintient la qualité du code élevé.