L'autre jour, je lisais un peu sur les tests unitaires et j'ai vu des exemples où les gens créent une interface de référentiel (c'est-à-dire IExampleRepository
) puis créent le vrai référentiel ( public class ExampleRepository : IExampleRepository
) et un référentiel à utiliser pour les tests unitaires ( FakeExampleRepository : IExampleRepository
).
Dans le, IExampleRepository
ils implémentaient les mêmes méthodes que dans le ExampleRepository
, mais avec des requêtes Linq différentes.
Quel est exactement l'objectif ici? Je pensais qu'une partie des tests unitaires de votre code est de s'assurer qu'une méthode fonctionne correctement? Mais lorsque j'utilise deux requêtes totalement différentes, une pour «réelle» et une dans le test, quel sens a le test?
ExampleRepository
, il est préférable d'utiliser une maquette. La justification étant que vous ne testez pas le référentiel, mais autre chose.ExampleRepository
, utilisez la vraie chose. Si vous êtes des tests unitairesRepositoryController
, il doit seulement utiliser uneFakeExampleRepository
qui renvoie des valeurs pré-spécifiées. De cette façon, si un bogue se glisse dansExampleRepository
, seul ce test unitaire échouera -RepositoryController
les tests de continueront à réussir, donc vous savez qu'il n'y a pas de bogue là-bas. Si le contrôleur utilisait le vrai référentiel, ils échoueraient tous les deux et vous ne sauriez pas si vous aviez 1 bogue ou 2.Je suis d'accord avec les deux réponses de jk. et Jan Hudec - ils donnent de très bonnes informations. Mais j'ai pensé ajouter un peu.
Votre première question ("Quel est exactement l'objectif ici?") Est importante. Dans le cas que vous décrivez, le véritable objectif est de tester les classes qui utilisent l'
IExampleRepository
interface, pas de tester les implémentations du référentiel. La création deFakeExampleRepository
vous permet de tester ces classes client sans vous soucier des détails de la classe de référentiel réelle.Cela est particulièrement vrai si l'objet que vous essayez de configurer rend les tests difficiles (par exemple, accède au système de fichiers, appelle un service Web ou parle à une base de données). En utilisant des interfaces (et d'autres techniques de ce type), vous maintenez le couplage bas. Par conséquent, la classe
X
n'a besoin que de connaître l'interface et n'a pas besoin de connaître les détails de l'implémentation. Le but est de s'assurer que la classeX
fait la bonne chose.La moquerie (ou le stubbing, le truquage ... il y a des différences nuancées) est un outil puissant pour les tests unitaires et TDD. Mais il peut être difficile de créer et de maintenir manuellement ces implémentations. Par conséquent, la plupart des langues ont maintenant des bibliothèques de simulation pour vous aider. Puisque vous utilisez C #, je recommanderais Moq car il est simple et très puissant. Ensuite, vous pouvez tester l'interface sans empiler de code supplémentaire pour les implémentations fictives.
la source
the real objective is to test the classes that are utilizing the IExampleRepository interface
ce n'est pas strictement vrai. L'objectif est de le tester indépendamment du IExampleRepository. +1 pour avoir recommandé un bon cadre d'isolement.IExampleRepository
car la classe testée est couplée à cette interface. Mais il est indépendant de toute implémentation de l'interface. Je dois admettre que mon explication pourrait probablement utiliser un peu plus de finesse. :)Isolement.
L'idée d'une unité le teste pour tester la plus petite unité de code possible . Vous faites cela en l' isolant de tout autre code de production dans le test.
En créant de fausses classes, le seul code de production est la classe testée.
Si vous créez correctement un faux référentiel et que le test échoue, vous savez que le problème vient du code en cours de test. Vous bénéficiez ainsi d'un diagnostic gratuit.
Jetez un œil aux frameworks d'isolement (comme Moq comme suggéré par @Allan) pour pouvoir générer ces contrefaçons rapidement pour configurer les conditions de test et les utiliser pour faire valoir.
la source
Il existe trois raisons pour lesquelles vous souhaiterez peut-être fournir une instance fictive au test unitaire:
la source