J'ai intitulé la question en plaisantant parce que je suis sûr que "ça dépend", mais j'ai quelques questions spécifiques.
Travaillant dans un logiciel qui comporte de nombreuses couches de dépendance profondes, mon équipe s'est habituée à utiliser le mocking assez largement pour séparer chaque module de code des dépendances en dessous.
Par conséquent, j'ai été surpris que Roy Osherove ait suggéré dans cette vidéo que vous ne devriez utiliser la moquerie que quelque chose comme 5% du temps. Je suppose que nous sommes assis entre 70 et 90%. J'ai vu de temps à autre d' autres conseils similaires .
Je devrais définir ce que je considère être deux catégories de "tests d'intégration" qui sont si distinctes qu'on devrait vraiment leur donner des noms différents: 1) les tests en cours qui intègrent plusieurs modules de code et 2) les tests hors processus qui parlent aux bases de données, aux systèmes de fichiers, aux services Web, etc. C'est le type # 1 qui m'intéresse, les tests qui intègrent plusieurs modules de code tous en cours.
Une grande partie des conseils de la communauté que j'ai lus suggère que vous devriez préférer un grand nombre de tests unitaires à grains fins isolés et un petit nombre de tests d'intégration de bout en bout à grains grossiers, car les tests unitaires vous fournissent des informations précises sur l'endroit exact où des régressions ont peut-être été créées, mais les tests grossiers, qui sont lourds à mettre en place, vérifient en fait davantage de fonctionnalités de bout en bout du système.
Compte tenu de cela, il semble nécessaire d'utiliser assez fréquemment la simulation pour isoler ces unités de code distinctes.
Étant donné un modèle d'objet comme suit:
... Considérez également que la profondeur de dépendance de notre application va beaucoup plus loin que je ne pourrais le faire dans cette image, de sorte qu'il existe plusieurs couches N entre la couche 2-4 et la couche 5-13.
Si je veux tester une simple décision logique prise dans l'unité # 1, et si chaque dépendance est injectée par le constructeur dans le module de code, cela en dépend tel que, disons, 2, 3 et 4 sont injectés par le constructeur dans le module 1 de l'image, je préfère de loin injecter des simulacres de 2, 3 et 4 en 1.
Sinon, j'aurais besoin de construire des instances concrètes de 2, 3 et 4. Cela peut être plus difficile que juste une frappe supplémentaire. Souvent 2, 3 et 4 auront des exigences de constructeur qui peuvent être difficiles à satisfaire et selon le graphique (et selon la réalité de notre projet), je devrai construire des instances concrètes de N à 13 pour satisfaire les constructeurs de 2, 3 et 4.
Cette situation devient plus difficile lorsque j'ai besoin de 2, 3 ou 4 pour se comporter d'une certaine manière afin de pouvoir tester la décision logique simple dans # 1. J'ai peut-être besoin de comprendre et de "raisonner mentalement" à la fois sur l'ensemble du graphique / arbre d'objet pour que 2, 3 ou 4 se comportent de la manière nécessaire. Il semble souvent beaucoup plus facile de faire myMockOfModule2.Setup (x => x.GoLeftOrRight ()). Returns (new Right ()); pour tester que le module 1 répond comme prévu lorsque le module 2 lui dit d'aller à droite.
Si je devais tester des instances concrètes de 2 ... N ... 13 ensemble, les configurations de test seraient très grandes et en grande partie dupliquées. Les échecs de test peuvent ne pas faire un très bon travail pour localiser les emplacements des échecs de régression. Les tests ne seraient pas indépendants ( autre lien de support ).
Certes, il est souvent raisonnable de faire des tests basés sur l'état plutôt que sur l'interaction de la couche inférieure, car ces modules ont rarement d'autres dépendances. Mais il semble que la moquerie soit presque nécessaire par définition pour isoler tous les modules au-dessus du plus bas.
Compte tenu de tout cela, quelqu'un peut-il me dire ce qui pourrait me manquer? Notre équipe utilise-t-elle trop les simulacres? Ou y a-t-il peut-être une hypothèse dans les conseils de tests unitaires typiques que les couches de dépendance dans la plupart des applications seront suffisamment peu profondes pour qu'il soit en effet raisonnable de tester tous les modules de code intégrés ensemble (ce qui rend notre cas "spécial")? Ou peut-être différemment, notre équipe ne délimite-t-elle pas adéquatement nos contextes délimités?
Or is there perhaps some assumption in typical unit testing guidance that the layers of dependency in most applications will be shallow enough that it is indeed reasonable to test all of the code modules integrated together (making our case "special")?
<- Ça.