Comment se moque-t-on des nombreuses dépendances nécessaires aux tests d'intégration?
J'utilise Mockito pour mes tests unitaires "purs". "Pure" dans ce cas signifie tester une seule classe, se moquer de toutes ses dépendances. Belle.
Viennent maintenant les tests d'intégration. Disons que dans ce cas, un test d'intégration testera quelque chose comme ceci:
Disons également que le traitement qui se produit à l'étape 2 est sérieux. Il repose sur de nombreuses interactions de bases de données, sur plusieurs services externes, le système de fichiers, toutes sortes de choses. Il y a aussi beaucoup d'effets secondaires que le flux déclenchera, donc je ne peux pas simplement m'assurer que la réponse est correcte - je dois vérifier les effets secondaires.
Chacune de ces dépendances est enveloppée par une seule classe de service sans état, ce qui les rend agréables et moquables.
Comment les gens gèrent-ils cela?
J'aimerais utiliser Mockito pour pouvoir vérifier les effets secondaires que le flux ci-dessus aura. Cependant, la documentation de Mocktio (et dans une large mesure son implémentation) semble lutter fortement contre son utilisation dans des contextes autres que les tests unitaires "purs". J'ai essayé de suivre cette voie, mais
MODIFIER
Je sais que je pourrais gérer le problème de base de données avec quelque chose comme une instance HSQLDB, mais il y a toujours le problème des services externes. Pour la répétabilité, je ne peux pas compter sur ces services étant en hausse, étant dans l'état dont j'ai besoin, etc. La seule option que je vois là est de se moquer d'eux.
Que faites-vous?
Grande question.
Il semble que vous ayez atteint les limites de Mockito. Mockito est idéal si vous voulez inspecter les interactions d'objets.
Ce que vous voulez, cependant, semble être l'observabilité (et la contrôlabilité) à un niveau d'abstraction plus élevé. Je crains que les moquettes ou les talons dont vous avez besoin pour cela soient soigneusement conçus et fabriqués à la main.
Au niveau de l'unité, ces simulations peuvent être bien générées, au moyen de Mockito. Au niveau de l'intégration, cela devient beaucoup plus difficile et vous aurez besoin d'interfaces de testabilité spécialement conçues.
Afin de se moquer de choses comme les bases de données, les services Web, le système de fichiers, etc., vous voudrez probablement refactoriser un peu. Pour chaque service externe, vous devez écrire une classe wrapper qui a une méthode pour chaque opération que vous souhaitez effectuer. Chacune de ces méthodes ne doit pas avoir de logique réelle, mais doit simplement passer ses paramètres de la manière que le service externe comprendra et retourner un objet qui contient toutes les données que le service externe renvoie. Par exemple, si vous interagissez avec une base de données, la classe wrapper peut formater ses paramètres dans une instruction SQL, les soumettre dans un objet Connection
existant et renvoyer un List
pour le résultat.
Parce que les méthodes de la classe wrapper ne contiennent aucune logique (c'est-à-dire pas de if/else, pas de boucles et pas de gestion des exceptions); il n'est pas nécessaire de tester à l'unité la classe wrapper. Vous devez tester l'intégration de la classe wrapper pour vous assurer que ses responsabilités sont exécutées correctement (c'est-à-dire que l'instruction SQL a l'effet souhaité sur la base de données, par exemple).
Maintenant, réécrivez les classes qui interagissent avec les services externes afin qu'elles interagissent avec les classes wrapper à la place. Il est alors facile de les tester à l'unité - il suffit de se moquer des classes wrapper.