Führt das Befolgen von TDD zwangsläufig zu DI?

14

Ich habe gelernt, Test Driven Development (TDD), Dependency Injection (DI) und Inversion of Control (IoC) gleichzeitig durchzuführen. Wenn ich mit TDD Code schreibe, verwende ich immer DI in den Konstruktoren meiner Klasse. Ich frage mich, ob dies daran liegt, wie ich TDD gelernt habe, oder ob dies eine natürliche Nebenwirkung von TDD ist.

Meine Frage lautet also: Führen die Befolgung von TDD-Prinzipien und das Schreiben von Komponententests, die nicht von externen Diensten abhängig sind, zwangsläufig zu DI?

Gilles
quelle
8
Ich lese The Art of Unit Testing und es scheint, dass es definitiv zu Dependency Injection (DI) führt.
Programmierer
2
Um welche Sprache handelt es sich? DI / etc sind in Java erforderlich, aber das liegt an einer Sprachbeschränkung - Sprachen wie Python benötigen es nicht, da sie in den Tests Patch-Abhängigkeiten aufweisen können.
Izkata
@ Izkata: Ich stimme zu, dass DI eine Problemumgehung für eine Spracheinschränkung ist. Monkeypatching ist jedoch in weniger strengen Sprachen nicht unbedingt dasselbe. Unter anderem bevorzuge ich erstklassige Funktionen, mit denen Sie natürlich das tun können, was DI durch Disziplin annähert.
Javier

Antworten:

19

Führt das Befolgen von TDD- und Schreibeinheitentests, die nicht von Datenbanken oder externen Diensten abhängig sind, zwangsläufig zu DI?

Für weite Definitionen von DI, ja. Klassen existieren nicht in einem Vakuum, daher müssen ihre Abhängigkeiten irgendwie gefüllt sein. Manchmal reicht es aus, nur einen Wert anzugeben. Manchmal muss im Konstruktor ein Mock angegeben werden. Manchmal über IoC-Container. Manchmal über privaten Testzugang. Es geht darum, ein Testobjekt in die Klasse zu injizieren, damit es isoliert funktionieren kann.

Telastyn
quelle
9

Für Leute, die bereits über DI Bescheid wissen, aber noch nie den Punkt gesehen haben, denke ich, dass Unit-Tests fast immer dazu führen werden, DI zu verwenden.

Wenn Sie nicht über DI Bescheid wissen und Unit-Tests schreiben möchten, werden manche Menschen DI auf natürliche Weise neu erfinden, andere werden frustriert sein und DI schließlich durch Recherchen entdecken, aber Sie wären überrascht, wie oft es einfach niemandem einfällt dass es eine bessere Möglichkeit geben könnte, ihre Software zu entwickeln, um das Testen von Einheiten zu vereinfachen. Diese Leute schreiben Unit-Tests als unlösbar ab und geben auf.

Karl Bielefeldt
quelle
8

Unit-Tests führen zu DI (da Sie dazu gezwungen sind, lose gekoppelte Units zu erstellen). TDD ist nicht unbedingt erforderlich, da TDD auch zum schichtweisen Erstellen von Tests anstelle von "wörtlichen" Komponententests verwendet werden kann. Siehe diesen Artikel

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

für eine Erklärung der Unterschiede.

Doc Brown
quelle
1
+1 für "TDD ist nicht UT". Auch um zu erkennen, dass die extreme Entkopplung ein häufiges Ergebnis von UT ist, nicht (notwendigerweise) von TDD.
Javier
3

Ja und Nein: TDD führt zum Schreiben von gut strukturiertem Code, der selbst zu DI führt.

Damit meine ich, dass TDD Ihnen im Allgemeinen den richtigen Weg in Bezug auf Verkapselung, SRP und Wiederverwendbarkeit zeigt. Es geht nicht nur darum, einige Tests für Ihren Code durchzuführen, sondern darum, mit diesen Tests ein besseres Design zu entwickeln. Wenn ein Objekt seine eigenen Abhängigkeiten erstellt, lebt es in einem bestimmten Kontext innerhalb einer bestimmten Anwendung und wird wahrscheinlich in größerem Maße in die Anwendung eingebunden. DI ist eine gute Sache, nicht nur in Bezug auf Tests, sondern auch in Bezug auf die Codequalität.

Tim
quelle
Können Sie das Nein zu Ihrer Ja- und Nein-Antwort klären? Wie macht man TDD ohne DI.
Gilles
Das "Nein" ist, dass ich nicht denke, dass es eine direkte Verbindung zwischen TDD und DI ist. Es ist indirekt über die Codequalität. Das spaltet wahrscheinlich die Haare, aber ich möchte nur darauf hinweisen, dass Sie auf Codequalität abzielen, nicht nur auf Testbarkeit.
Tim
0

Wie bereits in anderen Antworten ausgeführt, benötigt TDD keine Einheit Tests. Sie können auch Integrationstests / Funktionstests schreiben, während Sie TDD ausführen. Unter den verschiedenen Möglichkeiten, TDD anzuwenden, ist die Erstellung von Komponententests die Methode "Fake it till you make it" (Einzelheiten finden Sie im Buch von Kent Beck).

Was für "TDD führt unweigerlich zu DI", tut es definitiv nicht. Beim Schreiben von Unit-Tests muss die zu testende Unit von den Implementierungen ihrer externen Abhängigkeiten isoliert werden . Und das geht genauso einfach mit oder ohne DI. Der beste Weg ist wahrscheinlich, ein geeignetes Isolations- / Verspottungswerkzeug zu verwenden.

Rogério
quelle
Aber um Mocks zu benutzen, müssen Sie nicht unbedingt die Abhängigkeiten in die Klasse einbauen?
Gilles