Est-ce que suivre TDD mène inévitablement à DI?

14

J'ai appris à faire le développement piloté par les tests (TDD), l'injection de dépendance (DI) et l'inversion de contrôle (IoC) en même temps. Lorsque j'écris du code en utilisant TDD, je finis toujours par utiliser DI dans les constructeurs de ma classe. Je me demande si c'est à cause de la façon dont j'ai appris à faire du TDD, ou si c'est un effet secondaire naturel du TDD.

Ma question est donc la suivante: suivre les principes TDD et écrire des tests unitaires qui ne dépendent pas de services externes conduit-il inévitablement à DI?

Gilles
la source
8
Je lis L'art des tests unitaires et il semble que cela mène définitivement à l'injection de dépendance (DI).
programmeur
2
Alors de quelle langue s'agit-il? DI / etc est nécessaire en Java, mais c'est à cause d'une limitation de langage - les langages comme Python n'en ont pas besoin car ils peuvent singulariser les dépendances de patch dans les tests.
Izkata
@Izkata: Je suis d'accord que DI est une solution de contournement pour une limitation de langue; mais monkeypatching n'est pas nécessairement la même chose dans des langages moins rigides. Entre autres, je préférerais des fonctions de première classe, ce qui vous permet de faire naturellement ce que DI rapproche par discipline.
Javier

Réponses:

19

Est-ce que suivre TDD et écrire des tests unitaires qui ne dépendent pas de bases de données ou de services externes conduisent inévitablement à DI?

Pour des définitions larges de DI, oui. Les classes n'existent pas sous vide, elles doivent donc avoir leurs dépendances remplies d'une manière ou d'une autre. Parfois, il suffit de fournir une valeur. Parfois, vous devez fournir une maquette dans le constructeur. Parfois via des conteneurs IoC. Parfois via un accesseur de test privé. Tout cela injecte quelque chose de test dans la classe afin qu'il puisse fonctionner de manière isolée.

Telastyn
la source
9

Pour les personnes qui connaissent déjà DI, mais qui n'ont jamais vu le point, je pense que les tests unitaires conduiront presque invariablement à utiliser DI.

Si vous ne connaissez pas l' ID et essayez d'écrire des tests unitaires, certaines personnes réinventeront naturellement l'ID, certaines seront frustrées et finiront par découvrir l'ID par la recherche, mais vous seriez surpris de voir combien de fois cela n'arrivera tout simplement pas à quelqu'un qu'il pourrait y avoir une meilleure façon d'architecturer leur logiciel pour faciliter les tests unitaires. Ces gens considèrent les tests unitaires comme intraitables et abandonnent.

Karl Bielefeldt
la source
8

Les tests unitaires mèneront à DI (car ils vous obligent à créer des unités à couplage lâche). TDD pas nécessairement, car TDD peut également être utilisé pour créer des tests couche par couche, au lieu de tests unitaires "textuellement". Voir cet article

http://stephenwalther.com/archive/2009/04/11/tdd-tests-are-not-unit-tests.aspx

pour une explication des différences.

Doc Brown
la source
1
+1 pour "TDD n'est pas UT". Aussi pour reconnaître que l'extrême découplage est un résultat courant de l'UT, pas (nécessairement) du TDD.
Javier
3

Oui et non: TDD conduit à l'écriture d'un code bien structuré, qui lui-même conduit à DI.

J'entends par là que TDD vous envoie généralement la bonne voie en ce qui concerne l'encapsulation, la SRP et la réutilisabilité. Il ne s'agit pas seulement de faire des tests autour de votre code: il s'agit d'utiliser ces tests pour étoffer une meilleure conception. Si un objet crée ses propres dépendances, alors il vit dans un contexte spécifique au sein d'une application spécifique et est susceptible d'être tissé dans l'application à un degré plus élevé. DI est une bonne chose, non seulement du point de vue des tests, mais aussi du point de vue de la qualité du code.

Tim
la source
Pourriez-vous clarifier la partie non de votre réponse oui et non? Comment fait-on TDD sans DI.
Gilles
Le «non» étant je ne pense pas que ce soit un lien direct entre TDD et DI. C'est indirect via la qualité du code. Ce qui divise les cheveux probablement, mais je pensais simplement souligner que la qualité du code est la chose que vous visez, pas seulement la testabilité.
Tim
0

Comme déjà souligné dans d'autres réponses, TDD ne nécessite pas de tests unitaires . Vous pouvez tout aussi bien écrire des tests d'intégration / fonctionnels tout en faisant TDD. Parmi les différentes façons d'appliquer le TDD, la création de tests unitaires serait la méthode "fake it till you make it" (voir le livre de Kent Beck pour plus de détails).

Quant à «TDD conduit inévitablement à DI», il ne l'est certainement pas. Ce dont on a besoin lors de l'écriture de tests unitaires, c'est d' isoler l'unité testée des implémentations de ses dépendances externes. Et cela peut être fait tout aussi facilement avec ou sans DI. La meilleure façon est probablement d'utiliser un outil d'isolation / de moquerie approprié.

Rogério
la source
Mais pour utiliser des simulateurs ne faut-il pas nécessairement injecter les dépendances dans la classe?
Gilles