Après avoir lu quelques articles sur les objets Newable vs Injectable et comment ces concepts se rapportent aux services, entités et objets de valeur de DDD, je me suis posé quelques doutes quant à l'utilisation de newables dans mon code, en particulier dans mes tests unitaires.
Les principaux candidats pour les nouveautés étaient les objets Entités et Valeur, ce qui signifie qu'au lieu d'injecter ces dépendances dans d'autres objets, on devrait simplement new
une instance de ces objets et les utiliser directement dans le code.
Cependant, les bonnes pratiques DDD préconisent d'attribuer des responsabilités aux entités et aux objets de valeur s'ils sont jugés appropriés. Ainsi, les entités et les objets de valeur finiront par avoir une logique métier sérieuse.
Maintenant, si un service fonctionne sur une entité ou un objet de valeur, dois-je me moquer de l'entité ou de l'objet de valeur et passer la maquette au service (la moquerie nécessitera un interface
pour les objets de valeur ou les entités qui semble être déconseillé)?
Ou devrais-je simplement être new
un objet entité / valeur et transmettre une implémentation concrète au service et violer ainsi le principe de test unitaire de tester une seule unité?
Réponses:
Je lis que vous pensez que les tests unitaires, tout comme les objets SOLIDES, doivent avoir "une raison de casser". C'est un objectif noble, mais je pense que vous constaterez que dans de nombreux cas, il n'est tout simplement pas réalisable. Un de ces cas est ici, où vous avez un objet de domaine "riche" (DDD différencie les entités et les objets de valeur, qui comprennent tous les deux le "modèle de domaine") qui est une dépendance du système testé.
Dans ces situations, j'ai la philosophie que, étant donnél'objet de domaine a sa propre couverture de test unitaire complète, en espérant que l'objet fonctionnera comme prévu dans un test unitaire pour un SUT différent ne viole pas nécessairement le test unitaire. Si ce test venait à échouer en raison d'une rupture dans le domaine, je m'attendrais à ce que le test unitaire de l'objet domaine se casse également, ce qui m'amènerait vers quelque chose à enquêter. Si le test unitaire de l'objet de domaine a été correctement mis à jour en tant que test rouge, puis est devenu vert avec le changement, et cet autre test a ensuite échoué, ce n'est pas nécessairement une mauvaise chose non plus; cela signifie que les attentes de cet autre test sont en conflit avec les nouvelles attentes pour le domaine, et je dois m'assurer que les deux sont en accord les uns avec les autres et avec les critères d'acceptation généraux du système.
En tant que tel, je ne me moquerais d'un objet de domaine que si ledit objet de domaine produisait des "effets secondaires" qui n'étaient pas souhaitables du point de vue des tests unitaires (c'est-à-dire toucher des ressources externes comme des magasins de données), ou si la logique de l'objet de domaine était suffisamment complexe pour le placer dans l'état approprié pour le test devient un obstacle à la définition et à la réussite du test.
Cela devient alors la question déterminante; qui est plus facile? Pour utiliser l'objet de domaine à sa destination dans le test, ou pour se moquer de lui? Faites ce qui est le plus facile, jusqu'à ce que ce ne soit plus l'option la plus facile, comme lorsqu'un changement fonctionnel rompt le test du service de manière complexe; si cela se produit, réécrivez le test pour produire une maquette qui expose les exigences fonctionnelles dont dépend le service, sans la complexité qui le rompt.
Comprenez que dans les deux cas, il devrait y avoir un test d'intégration qui utilise l'objet de domaine réel connecté au service réel qui teste l'interaction entre ces deux à un niveau d'abstraction plus élevé (comme le test, par exemple, non seulement la fonctionnalité derrière un service mais un proxy à travers lequel l'objet de domaine est sérialisé et envoyé).
la source
Faire confiance à la classe dépendante pour qu'elle fonctionne correctement, en espérant que certains tests unitaires échoueraient lorsque quelque chose ne fonctionne pas, alors cela devrait être testé très bien . Peut-être qu'il manque des tests unitaires importants? Il peut y avoir un cas non testé qui créerait une erreur, qui sera produit dans ma classe de test d'origine et ne serait pas intercepté dans la classe dépendante elle-même.
Donc, à mon avis pour les tests unitaires, les classes dépendantes devraient être moquées. Si ce n'est pas le cas, alors c'est un test d'intégration.
la source