Wann sollte ich Scheinobjekte verwenden?

14

Ich habe viel über TDD gelesen, aber ich habe immer noch Zweifel. Zum Beispiel habe ich diese Klassendiagramme:

Bildbeschreibung hier eingeben

Es ist ein einfaches Beispiel, um TDD und Scheinobjekte kennenzulernen.

Welchen Test soll ich zuerst schreiben? Produkt , dann Linie und zuletzt Bestellung ? Wenn ich das tue, sollte ich Line and Product verwenden , um die Bestellung zu testen, oder sollte ich Mock Objects verwenden? Wann sollte ich Mock Objects verwenden? Sollte ich UML mit XP und TDD verwenden?

Ich verstehe diese Dinge noch nicht.

Zanon
quelle

Antworten:

10

Nach dem Diagramm ist Product eine dumme Datenklasse ohne zu testende Funktionalität. Also würde ich anfangen, Tests für (und die Implementierung im TDD-Stil) zuerst Line und dann Order zu schreiben, die Abhängigkeitsleiter hinauf. In der Regel ist es sinnvoll, die Klassen niedrigerer Stufen zu testen, bevor Sie mit der Arbeit an Klassen höherer Stufen beginnen (dh die von den Klassen niedrigerer Stufen abhängen). Dies macht das Fangen von Bugs effizienter.

Ob Sie Scheinobjekte verwenden müssen, hängt von den tatsächlichen Abhängigkeiten der getesteten Klasse ab. Wenn es sich um einfache Klassen handelt, die Sie einfach instanziieren und mit den für Ihre Tests erforderlichen Daten / Zuständen einrichten können, benötigen Sie keine Verspottungen. (Dies scheint für Ihr Beispieldesign hier der Fall zu sein.) Wenn jedoch eine der Abhängigkeiten schwierig zu initialisieren ist / umfangreiche Abhängigkeiten aufweist / unerwünschte Nebenwirkungen aufweist / von einer externen Ressource wie einer Datenbank abhängt, ist dies sinnvoll um stattdessen ein Scheinobjekt zu verwenden.

Péter Török
quelle
Wie ich bereits sagte, war es ein einfaches Szenario, nur um etwas über TDD- und Mock-Objekte zu lernen ... Eine großartige Antwort, danke. Und was ist mit UML? Sollte ich es vermeiden?
@ Thomas, keine Notwendigkeit, UML zu vermeiden, widerspricht es nicht mit TDD. UML eignet sich sehr gut zur Visualisierung / Kommunikation von Designproblemen. Dies kann in bestimmten Entwicklungsstadien äußerst nützlich sein. Das Design entwickelt sich jedoch weiter, und der Versuch, ein schönes und detailliertes UML-Systemdiagramm mit dem Code zu synchronisieren, kann schnell zur Belastung werden. Denken Sie also daran, es wegzuwerfen, wenn Sie es nicht mehr benötigen :-)
Péter Török
1
@thomas, übrigens ist die Konvention hier, um Antworten, die Sie nützlich finden, durch Klicken auf den Aufwärtspfeil neben der Antwort
Péter Török
4

Ich sehe hier keinen großen Bedarf an Scheinobjekten. Wie bereits erwähnt, benötigen Sie diese meistens, wenn Abhängigkeiten schwer einzurichten sind.

Beispielsweise haben wir sie in Ruby on Rails-Projekten verwendet, als wir Controller getestet haben und eine Benutzeranmeldung benötigten, die einen Aufruf an einen anderen Controller und das Speichern eines Teils seiner Informationen in einem Cookie erfordert hätte. In diesem Fall ist es hilfreich, einen angemeldeten Benutzer zu verspotten, der true zurückgibt, wenn er nach einem bestimmten Zugriffsrecht gefragt wird.

thorsten müller
quelle
2

Normalerweise möchten Sie zu Testzwecken das zu testende System / Objekt isolieren, damit Sie alles verspotten, was sich außerhalb davon befindet. Verwenden Sie also beim Testen eines Auftragsobjekts mithilfe Ihres Klassendiagramms einen Schein für das Linienobjekt. Verwenden Sie beim Testen von Line einen Schein für Bestellung und Produkt. Verwenden Sie beim Testen des Produkts den Schein für Line.

BlackICE
quelle
Da das Produkt nicht von der Linie abhängt, besteht keine Notwendigkeit (und auch keine Möglichkeit), dort eine Kopie für die Linie zu verwenden. Gleiches gilt für Line and Order.
Péter Török
2

"TDD ist in erster Linie eine Designtechnik mit dem Nebeneffekt, dass Ihr Quellcode gründlich auf seine Einheit getestet wird" - Scott W. Ambler

Die Idee ist, das Design durch Schreiben von Komponententests zu finden. In Ihrem Fall scheint das Design bereits vorhanden zu sein, was den Zweck von TDD in gewisser Weise zunichte macht (vorausgesetzt, Ihr Design ist endgültig).

In Bezug auf das Verspotten. Wenn Sie verspotten möchten, empfehle ich Ihnen, das Produkt zu verspotten, wenn Sie Tests für Line schreiben, und Line zu verspotten, wenn Sie Order testen. Aber es kann hier übertrieben sein. Ich persönlich versuche, das Verspotten so weit wie möglich zu begrenzen und Abhängigkeiten von externen Klassen (z. B. Datenbankinstanzen) zu entkoppeln.

Martin Wickman
quelle
2
Ich habe nur ein einfaches Klassendiagramm ...
-1 Wenn Sie also über das Design nachdenken (einschließlich des Aufschreibens eines Klassendiagramms), können Sie kein TDD durchführen? Das klingt einfach falsch.
Bjarke Freund-Hansen
1
@bjarkef: Lies meine Antwort bitte nochmal. Wenn das Design endgültig ist, können Sie TDD nicht wirklich zum Vertreiben des Designs verwenden, worum es bei TDD geht. Und ich denke, dies ist auch das, was das OP verwirrt: Er hat bereits eine Lösung und versucht nun, Tests dafür zu schreiben. Msgstr "Welche Tests soll ich zuerst schreiben, Produkt oder Bestellung". Diese Frage ist nicht wirklich relevant, wenn Sie zuerst Tests schreiben.
Martin Wickman
Wie stellen Sie fest, dass das Design ohne Tests oder Produktionscode endgültig ist? Angenommen, Sie möchten etwas erstellen, das funktioniert.
JeffO
@ Jeff: Das kannst du natürlich nicht. Das ist eine Sache, bei der TDD Ihnen helfen kann.
Martin Wickman