Tests unitaires et moquerie
Il semble y avoir beaucoup de questions concernant "quand se moquer". Mais je n'ai pas encore obtenu de réponse à ma question. Cela peut être, je ne connais pas de demande de recherche spécifique qui me dirigerait vers la réponse.
Imaginez que nous ayons une classe (MyClass). Imaginez que cette classe a des méthodes qui peuvent renvoyer à la fois std :: string et un objet de classe wrapper (MyStringWrapper défini dans une autre bibliothèque). MyStringWrapper n'est pas exactement un agrégateur (nous pouvons envisager d'utiliser struct ici, mais préférons une classe pour cet exemple particulier), car son setter a un if et plusieurs opérations de copie. Maintenant, il existe une 3ème classe (UserClass) qui utilise les classes MyClass et MyStringWrapper.
En tant que bon développeur de logiciels, j'aimerais tester mon UserClass unitaire (car beaucoup font référence à «sentir un code»). Pour les tests unitaires, j'utiliserais gtests et gmock pour créer une maquette de MyClass (appelons-la MyClassMock). Cependant, je me souviens que quelque part on disait "il faut se moquer de tout, ce qui est défini dans une autre bibliothèque / bibliothèque tierce". Les deux std :: string et MyStringWrapper sont définis dans des bibliothèques tierces.
Maintenant la question. Alors, dois-je dans ce cas créer des simulations pour std :: string et MyStringWrapper?
Vous pouvez imaginer l'utilisation de l'objet std :: string / MyStringWrapper renvoyé comme
if(myreturnedstdstring.empty())
return 1;
if(mywrapperobject.failed())
return 100;
On m'a demandé dans les commentaires ici Y a-t-il un point aux tests unitaires qui stub et simulent tout public?
créer un autre sujet.
Réponses
Tout ce qui se trouve dans std :: fait partie du langage et ne doit pas être moqué. Votre wrapper de chaîne, s'il ne fait pas partie de l '«unité» sous test, peut être moqué, mais à mon humble avis et l'expérience d'un wrapper comme celui-ci est généralement si léger que le simulacre reproduirait essentiellement le code. Dans ce cas, je ne m'en moquerais pas. Cependant, si le wrapper peut changer dans le futur, vous devriez vous en moquer si vous voulez un test unitaire stable. D'un autre côté, l'échec d'un test lorsqu'une modification incompatible est apportée au wrapper serait une bonne chose, mais plus difficile à retrouver puisque l'erreur se trouvera dans une autre unité.
Je me souviens que quelque part, il a été dit "vous devez vous moquer de tout, ce qui est défini dans une autre bibliothèque / bibliothèque tierce".
Cela a peut-être été le conseil à un moment donné, mais ce n'est pas le conseil qui est communément donné aujourd'hui.
Le conseil actuel est d'utiliser la simulation avec parcimonie pour aider à atteindre ces objectifs des tests unitaires:
- Les tests peuvent être exécutés rapidement, en parallèle ou dans n'importe quel ordre et à tout moment. Cela implique que les composants qui interagissent avec le stockage persistant (bases de données, systèmes de fichiers), les connexions lentes (réseau) ou les conditions environnementales que vous ne pouvez pas contrôler facilement (par exemple le temps) sont des candidats à la dérision.
- Tous les chemins à travers le code sous test peuvent être exercés. Si une certaine réponse (d'erreur) d'une dépendance ne peut pas être facilement déclenchée avec le code réel, cela pourrait être une raison de se moquer de cette dépendance.
Les types de données simples, comme les chaînes, votre MyStringWrapper ou même les conteneurs ne correspondent pas à ces points, il n'y a donc aucune raison de se moquer d'eux.