Welche Szenarien, Bereiche einer Anwendung/eines Systems usw. eignen sich am besten für "klassische" zustandsbasierte Tests im Vergleich zu Mock-Objekten?Woher weiß ich, wann ein zustandsbasiertes Testen im Vergleich zu einem Scheintest verwendet werden soll?
Antwort
Sie sollten Mocks für Abhängigkeiten verwenden. Ich glaube nicht, dass es ein Entweder-Oder ist; In der Regel werden Sie Mocks für Abhängigkeiten erstellen, die Erwartungen (ob es sich um Anrufe oder Status handelt) für sie festlegen und dann die zu testende Einheit ausführen. Dann würden Sie seinen Zustand überprüfen und anschließend die Erwartungen an die Mocks überprüfen.
Die Verwendung von Mock-Objekten bedeutet nicht, dass Sie nicht State-Based-Tests durchführen.
Es ist eine Frage des Stils .. Mockist vs Classic TDDers.
Persönlich .. Ich würde so weit wie möglich reale Klassen testen gehen. Reduziere so viel wie möglich auf Mocks. nur um Dinge wie IO (Dateisysteme, DB-Verbindungen, Netzwerk), Komponenten von Drittanbietern, etc. Dinge zu entkoppeln, die langsam/schwer zu testen sind.
Als erfahrener TDD'er, das ist eine Frage, die ich oft von anderen Entwicklern gestellt werde. Für mich ist es ein Fehler, in eine mockistisch-klassizistische Debatte hineingezogen zu werden, da eine solche Diskussion irreführend ist. State-based und behaviour-based Unit Testing sind zwei verschiedene Werkzeuge in Ihrer Toolbox, und es gibt keinen Grund, warum sie sich gegenseitig ausschließen sollten.
State-based Unit Testing eignet sich, wenn Sie die internen Eigenschaften eines Objekts abfragen möchten, nachdem Sie mit seiner externen Schnittstelle gesprochen haben. Wenn einer oder mehrere Mitarbeiter potentiell teure Anrufe an andere Objekte ausführen, stempeln Sie diese Anrufe auf jeden Fall ab und ignorieren Sie die Mitarbeiter einfach.
Verhaltensbasierte Komponententests sind eine gute Idee, wenn Sie das "Wie" eines Komponententests betrachten und sich auf die Ermittlung von Beziehungen zwischen Objekten konzentrieren möchten, im Gegensatz zu den traditionellen "Was" -Fragen eines zustandsbasierten Komponententests . Wenn Sie bestätigen möchten, dass Mitarbeiter in einer bestimmten Weise und/oder Reihenfolge verwendet werden, verwenden Sie mocks - stubs, die Assertions bereitstellen.
Ich schlage vor, Sie konzentrieren sich auf Standard-Unit-Testpraktiken - üben Sie so wenig Produktionscode wie möglich, und eine Assertion pro Test. Dies wird Sie zwingen zu denken, "was genau möchte ich in diesem Test ausüben und behaupten?", Und die Antwort auf diese Frage wird Ihnen helfen, die richtigen Unit-Test-Tools zu wählen.
Ich werde es aus einer TDD/BDD-Perspektive angehen, wo die Tests die Designs vorantreiben.
Zunächst einmal hängt es davon ab, welchen Stil des Designs Sie kaufen, denn erinnern Sie sich, dies ist über Design zuerst. Wie Martin Fowler in diesem ausgezeichneten Artikel Mocks Aren't Stubs diskutiert, gibt es zwei Gedankenschulen und sie produzieren verschiedene Arten von Designs.
Wenn Sie in den Mockist Ansatz kaufen wollen dann empfehle ich Ihnen sehr beginnen an der mockobjects site und ihrem Artikel Mock Roles, Not Objects suchen. Sie haben auch eine book herauskommen.
Die Wahrheit ist, selbst wenn Sie glauben, dass der Mock-First-Stil des Designs nicht für Sie ist, oder dass Sie es nicht direkt durch Ihre Anwendung tun möchten (zB nicht beim Testen Ihrer Domain/Service-Ebene) dann werden Sie immer noch Testdoppel verwenden wollen. xUnit Test Patterns erklärt die verschiedenen Arten von Testdoppel und ihre Zwecke.
Ich persönlich nie Domain-Klassen, also niemals mocking entities/value objects.Allerdings habe ich in letzter Zeit die Mock-Objects-Style-Methode viel ausprobiert, es ändert meine Designs ein wenig und ich finde den Arbeitsstil bequem. Wenn ich in dieser Art in einer MVC-App arbeite, beginne ich wahrscheinlich mit einem automatisierten Akzeptanztest, dann schreibe ich einen Controller-Test, der alle Nicht-Domänenobjekte (z. B. Repositories/Dienste) ausspioniert, dann gehe ich zum Testen über diese Repositories/Dienste spotten wieder über ihre Abhängigkeiten. Ich höre auf, wenn ich eine Klasse ohne störende Abhängigkeiten erreiche, z. B. ein Domain-Objekt/Wert-Objekt. Ich könnte weitermachen und gegen spezifische Rollenschnittstellen testen, die dann von meinen Domänenklassen implementiert werden, was die Leute von den Scheinobjekten empfehlen würden, aber ich sehe derzeit keinen großen Wert in diesem Ansatz.
Offensichtlich ist es wert, fügte hinzu, dass Design für Test hier wichtig ist, aber denken Sie daran, dass, obwohl 90% der IoC/spöttischen/DIP Beispiele zeigen interface-implementation pairs (ICustomerRepository/CustomerRepository) gibt es eine Menge Wert in anstatt für role interfaces suchen.
Bei der Verwendung von Diensten, egal ob von mir selbst oder von Drittanbietern, entwerfe ich natürlich Schnittstellen, daher konzentriere ich mich auf die Interaktionen dort. Dies ermutigt mich, minimale Schnittstellen zu entwerfen.
Ich überprüfe Zustand auf alles, das sich auf Wertobjekte konzentriert, ebenso wie einfache Berechnungen, Nachschlagewerke und dergleichen.
Wenn Sie das nächste Mal etwas entwerfen, das typischerweise Model/View/Controller-or-Presenter folgt, empfehle ich den Presenter First-Ansatz (Google it) mit den Schnittstellen für Model und View. Dies gibt Ihnen ein großartiges Gefühl für die effektive Verwendung von Stubs/Mocks.
- 1. Woher weiß CMake, welche Version von Qt verwendet werden soll?
- 2. Woher weiß Swift zur Laufzeit, welche Implementierung verwendet werden soll?
- 3. Wann @ in einer Rails-Ansicht verwendet werden soll und wann ein Symbol verwendet werden soll?
- 4. Java: Woher weiß ich, welche JAR-Datei bei einem Klassennamen verwendet werden soll?
- 5. Woher weiß Angular 2, woher es importiert werden soll?
- 6. Woher weiß ich, wann ich ein Objekt entsorgen muss?
- 7. Woher weiß ich, wann ein Amazon EC2-Vorgang abgeschlossen ist?
- 8. Woher weiß ich, wann ein Kindprozess gestorben ist?
- 9. Wann Anwendungskontext in Springs verwendet werden soll.
- 10. Woher wissen Sie, wann Designmuster verwendet werden?
- 11. Java - Wann dieses '' 'Schlüsselwort verwendet werden soll
- 12. Woher weiß ich, wann ein Fenster erstellt wird?
- 13. Woher wissen Sie, wann Sie einen XML-Parser verwenden und wann ActiveResource verwendet werden soll?
- 14. Woher weiß man, wo AS Schlüsselwort verwendet werden sollte?
- 15. Woher weiß ich, wann __cxa_throw an einem All Exceptions Breakpoint ignoriert werden kann?
- 16. Woher weiß ich, wann ich `const ref` oder` in` benutzen soll?
- 17. Woher weiß ich, wann der letzte OutputDataReceived angekommen ist?
- 18. Woher weiß ich, wann eine ListBox in Silverlight gerendert wurde?
- 19. AWS Kostenloses Konto, woher weiß ich, wann ich belastet werde?
- 20. Woher weiß ich, wann ein Anhangsattribut zu meiner NSTextView hinzugefügt wird?
- 21. Wie AccountManager weiß, welches Google-Konto verwendet werden soll?
- 22. node.js async.all Callback, woher weiß ich, wann es fertig ist?
- 23. Wie weiß die JVM, wann eine NullPointerException ausgelöst werden soll
- 24. Wann sollte ein Schlüssel/Wert-Datenspeicher im Vergleich zu einer traditionelleren relationalen Datenbank verwendet werden?
- 25. Woher weiß das Betriebssystem, welche Netzwerkschnittstelle für das Internet verwendet werden soll?
- 26. Wann ein neues Repository erstellt werden soll?
- 27. Woher weiß man, wann ein Benutzer irgendwo war?
- 28. Wann sollte ein IOC-Container verwendet werden?
- 29. Woher weiß ich, ob ein BigDecimal nicht analysiert werden konnte?
- 30. Wann sollte ich die Steuerelemente manuell entsorgen? Woher weiß ich, ob ein Steuerelement IDisposable implementiert?
+1 ... und das Buch ist raus: http://www.growing-object-oriented-software.com/ –