2008-10-08 2 views
9

Nachdem ich Martin Fowlers Mocks Aren't Stubs gelesen habe, habe ich entdeckt, dass ich TDD auf "Spott" -Mode geübt habe.Als "spöttischer" TDD-Praktizierender sollte ich andere Methoden in der gleichen Klasse wie die zu testende Methode verspotten?

Aber ich frage mich, ob selbst in Pseudo-TDD, wenn man sich zu weit spotten kann.

Hier ist ein Beispiel in Python-Stil Pseudo-Code aktualisiert:

def sync_path(self): 
    if self.confirm_or_create_connection(): 
     self.sync(self.dirpath) 

Die confirm_or_create_connection() Methode erstellt eine Verbindung zu einem Server.

Ich testete eine ähnliche Methode in zwei Tests, die beide confirm_or_create_connection() und sync() vortäuschen (obwohl sie beide Methoden in der gleichen Klasse sind). In einem Test gibt der Schein confirm_or_create_connection() True zurück und der Test bestätigt, dass sync() aufgerufen wurde, und in dem anderen gibt der Schein confirm_or_create_connection() False zurück und der Test bestätigt, dass sync() nicht aufgerufen wurde.

Ist das sinnvoll? Oder sollte ich die Objekte vortäuschen, die confirm_or_create_connection() und sync() aufrufen? (Ich habe andere Tests dieser beiden Methoden, die das bereits tun.)

Bitte beantworten Sie die Frage nicht, indem Sie erklären, dass ich stattdessen "klassische" TDD üben sollte. Das ist eine Antwort auf eine andere Frage: Should I practice mockist or classical TDD?

Antwort

8

Die Technik heißt aus gutem Grund "Mock-Objekte", nicht "Mock-Methoden". Es fördert Designs, die das System in leicht komponierte, kollaborierende Objekte und weg von prozeduralem Code aufteilen. Ziel ist es, das Abstraktionsniveau zu erhöhen, so dass Sie hauptsächlich durch das Zusammensetzen von Objekten programmieren und selten Low-Level-Kontrollflussanweisungen schreiben.

1

für das neue Beispiel bearbeitet
Für mich sieht es aus wie Sie confirm_or_create_connection sind Anstoßen, sind Sie nur daran interessiert, den Rückruf bei der Definition und Sie sync spöttisch, hier Sie sind daran interessiert zu testen, ob es wirklich heißt. (Ich muss überprüfen, ob meine Definition von Stubbing oder Mocking die gleiche ist wie der Fowler-Artikel, auf den Sie verwiesen haben. Es ist schon eine Weile her, dass ich es gelesen habe und ich habe Rhinomocks in C# verwendet, die eine eigene Verteidigung haben könnten diese Begriffe :-))

Ich denke für das, was Sie testen, spotten und stottern diese Anrufe ist der richtige Weg zu gehen. Sie möchten nicht testen, dass ein Fehler auftritt, wenn eine dieser Funktionen einen Fehler aufweist. Dafür gibt es andere Tests. Sie möchten nur den Betrieb von sync_path testen.

Ich stimme Avdi, dass dies eine Art von stinkend ist. Die Tests sind in Ordnung, aber Ihre Klasse könnte zu viel tun.

+0

Ich werde versuchen, meine Frage klarer zu machen. –

5

Persönlich denke ich, dass das Spotten auf Selbst fast immer ein Code-Geruch ist. Es testet die Implementierung und nicht das Verhalten.

+0

Aber was ist, wenn eine Funktion kein Ergebnis liefert - nur Nebenwirkungen? (Wie in meinem obigen Beispiel.) –

+0

Abhängig von der Situation würde ich entweder die confirm_or_create_connection() -Aufrufe stub/mock machen, oder ich würde confirm_or_create_connection() auf ein enthaltenes Objekt setzen und eine Stub-Implementierung dieses Objekts zur Testzeit ersetzen . – Avdi

0

Können Sie sich zu weit spotten? Ich weiß nicht über zu viel, aber es kann schlecht so gemacht werden, dass Sie tatsächlich die Mocks anstelle des Codes testen, oder schlechter, so dass Sie brüchige Tests haben.

Aber solange Sie gute Tests schreiben - Tests, die Ihr erwartetes Verhalten bestätigen, Tests, die Ihnen helfen, den Code zu schreiben - dann spotten Sie!

4

Bearbeitet für aktualisierten Beispiel:

Ich sehe jetzt. Sie haben Probleme beim Testen dieser Klasse, da sie Konstruktionsfehler aufweist. Diese Klasse verletzt das Prinzip der einheitlichen Verantwortung. Es macht zwei Dinge. Zuerst verwaltet es eine Verbindung zu einer Datenbank. Es synchronisiert auch.

Sie benötigen eine separate Klasse, um Ihre Datenbankverbindung zu verwalten. Diese Klasse ist eine Abhängigkeit der getesteten Klasse.Die Datenbankverbindungsklasse kann gefälscht werden, wenn Sie die zu testende Klasse im Unit-Test testen.

Früher:

Als Stipendiatin Interaktion Tester betrachten Refactoring, wenn Sie eine Notwendigkeit, dies zu tun. Diese Klasse ist wahrscheinlich zu viel.

Lassen Sie mich es Ihnen so sagen: Aufruf eine private Methode macht keine Interaktion.

Dies ist einer der Hauptpunkte von TDD. Wenn es weh tut Ihr Design kann verbessert werden.

1

wild Erraten, es sieht aus wie die Verbindungsaktivität könnte in einem anderen Objekt gehört, die übertragen werden soll, in diesem Fall Sie dass verspotten. Ich empfehle normalerweise, einen Teil eines Objekts zu verspotten, um einen anderen Teil zu testen. Es deutet darauf hin, dass zwei Konzepte miteinander verschraubt sind.

0

Hier ist ein gutes Buch auf es: „Prinzip: Setzen Sie das SUT nicht ändern“ bei http://xunitpatterns.com/Principles%20of%20Test%20Automation.html#Don

Ändern der Klasse, die Sie testen sind durch spöttische oder Teile ihrer Umsetzung Anstoßen ein Code Geruch ist. Das Refactoring, um davon wegzukommen, besteht darin, den Teil, den Sie verspotten, in eine andere Klasse zu verschieben. Das sagte, es ist nicht immer eine schreckliche Sache. Es ist ein Code-Geruch, aber es ist nicht immer unpassend. Für Sprachen wie C# oder Java, wo Sie gute Refactoring-Tools haben, ist es einfach, diesen Code-Geruch zu beheben und ich würde normalerweise (in C#, vorausgesetzt Java ist ähnlich). Ich mache viel Entwicklung in Lua und Javascript, wo die Dinge ein wenig anders sind. Das Erstellen und Verwalten von vielen Klassen in diesen Sprachen ist schwieriger, daher bin ich toleranter beim Modifizieren des SUT in Tests. Es ist immer etwas, was ich später beheben kann, sobald die erste Testabdeckung da ist. Es erfordert besondere Sorgfalt.