Wie schreibe ich einen Mockist-Test einer rekursiven Methode

8

Wenn ich eine Methode habe, die sich unter einer bestimmten Bedingung aufruft, ist es möglich, einen Test zu schreiben, um das Verhalten zu verifizieren? Ich würde gerne ein Beispiel sehen, ich interessiere mich nicht für das falsche Framework oder die Sprache. Ich verwende RhinoMocks in C #, also bin ich neugierig, ob es ein fehlendes Feature des Frameworks ist oder ob ich etwas Grundlegendes falsch verstehe oder ob es nur eine Unmöglichkeit ist.

    
JeremyWeir 11.02.2010, 02:05
quelle

5 Antworten

4

Angenommen, Sie möchten etwas wie den Dateinamen von einem vollständigen Pfad abrufen, zum Beispiel:

%Vor%

und Sie haben:

%Vor%

und Sie möchten schreiben:

%Vor%

Rekursion ist hier ein Implementierungsdetail und sollte nicht getestet werden. Sie möchten wirklich zwischen den beiden Implementierungen wechseln und überprüfen können, ob sie das gleiche Ergebnis liefern: Beide erzeugen lol.cs für die drei obigen Beispiele.

Da Sie rekursiv mit Namen arbeiten und nicht thisMethod.again () usw. sagen, können Sie in Ruby die ursprüngliche Methode mit einem neuen Namen versehen, die Methode mit dem alten Namen neu definieren und den neuen Namen aufrufen und prüfen Sie, ob Sie in der neu definierten Methode landen.

%Vor%     
miaubiz 28.02.2010, 11:23
quelle
6
  

eine Methode, die sich unter einer bestimmten Bedingung aufruft, ist es möglich, einen Test zu schreiben, um das Verhalten zu verifizieren?

Ja. Wenn Sie jedoch die Rekursion testen müssen, trennen Sie den Einstiegspunkt für Testzwecke besser in den Rekursions- und den Rekursionsschritt.

Wie auch immer, hier ist das Beispiel, wie man es testet, wenn man das nicht kann. Sie brauchen nicht wirklich zu spotten:

%Vor%     
Dmytrii Nagirniak 03.03.2010 01:39
quelle
4

Sie missverstehen den Zweck von Scheinobjekten. Mocks (im mockistischen Sinne) werden verwendet, um Verhaltensinteraktionen mit Abhängigkeiten des zu testenden Systems zu testen.

Sie könnten also beispielsweise Folgendes haben:

%Vor%

Coyote hängt von IMailOrder ab. Im Produktionscode würde einer Instanz von Coyote eine Instanz von Acme übergeben, die IMailOrder implementiert. (Dies kann durch manuelle Dependency-Injektion oder über ein DI-Framework erfolgen.)

Sie möchten die Methode CatchDinner testen und sicherstellen, dass sie OrderExplosives aufruft. Um dies zu tun, Sie:

  1. Erstellen Sie ein Mock-Objekt, das IMailOrder implementiert, und erstellen Sie eine Instanz von Coyote (das zu testende System), indem Sie das Mock-Objekt an seinen Konstruktor übergeben. (Anordnen)
  2. Rufen Sie CatchDinner an. (Akt)
  3. Bitten Sie das Mock-Objekt, zu überprüfen, ob eine bestimmte Erwartung (OrderExplosives genannt) erfüllt wurde. (Bestätigen)

Bei der Einrichtung hängen die Erwartungen an das Mock-Objekt möglicherweise von Ihrem (isolierenden) Spottwerk ab.

Wenn die zu testende Klasse oder Methode keine externen Abhängigkeiten aufweist, müssen (oder wollen) Sie für diese Tests keine Mock-Objekte verwenden. Es spielt keine Rolle, ob die Methode rekursiv ist oder nicht.

Sie möchten im Allgemeinen Randbedingungen testen, sodass Sie einen Aufruf testen können, der nicht rekursiv sein soll, einen Aufruf mit einem einzelnen rekursiven Aufruf und einen tief rekursiven Aufruf. (Miaubiz hat jedoch einen guten Punkt, dass die Rekursion ein Implementierungsdetail ist.)

BEARBEITEN: Mit "Aufruf" im letzten Absatz meinte ich einen Aufruf mit Parametern oder Objektstatus, der eine bestimmte Rekursionstiefe auslösen würde. Ich würde auch empfehlen, The Art of Unit Testing zu lesen.

BEARBEITEN 2: Beispiel für einen Testcode mit Moq :

%Vor%     
TrueWill 03.03.2010 03:48
quelle
1

Es gibt nichts zu überwachen Stack-Tiefe / Anzahl von (rekursive) Funktionsaufrufe in jedem Spott-Framework, die ich kenne. Das Testen der Einheit, dass die richtigen Bedingungen die richtigen Ausgaben liefern, sollte jedoch der gleiche sein wie das Spotten einer nicht-rekursiven Funktion.

Unendliche Rekursion, die zu einem Stack-Überlauf führt, müssen Sie separat debuggen, aber Unit-Tests und Mocks haben diesen Bedarf überhaupt erst beseitigt.

    
Tanzelax 11.02.2010 02:18
quelle
0

Hier ist mein "Bauern" -Ansatz (in Python, getestet, siehe die Kommentare für die Begründung)

Beachten Sie, dass das Implementierungsdetail "Exposure" hier nicht in Frage kommt, da das, was Sie testen, die zugrundeliegende Architektur ist, die zufällig vom "Top-Level" -Code verwendet wird. Also, es zu testen ist legitim und brav (ich hoffe auch, es ist, was Sie im Sinn haben).

Der Code (die Hauptidee besteht darin, von einer einzelnen, aber "nicht testbaren" rekursiven Funktion zu einem äquivalenten Paar rekursiv abhängiger (und damit testbarer) Funktionen zu gehen):

%Vor%

Der Test:

%Vor%

Die Ausgabe:

%Vor%     
mlvljr 03.03.2010 17:20
quelle