2012-08-02 10 views
58

Ich möchte Mockito verwenden, um den (vereinfachten) Code unten zu testen. Ich weiß nicht, wie ich Mockito das erste Mal zum Scheitern bringen soll, dann zum zweiten Mal.Simulate ersten Anruf schlägt fehl, zweiter Anruf ist erfolgreich

for(int i = 1; i < 3; i++) { 
    String ret = myMock.doTheCall(); 

    if("Success".equals(ret)) { 
    log.write("success"); 
    } else if (i < 3) { 
    log.write("failed, but I'll try again. attempt: " + i); 
    } else { 
    throw new FailedThreeTimesException(); 
    } 
} 

ich kann Setup den Erfolg Test mit:

Mockito.when(myMock).doTheCall().thenReturn("Success"); 

Und die Fehlerprüfung mit:

Mockito.when(myMock).doTheCall().thenReturn("you failed"); 

Aber wie kann ich testen, wenn es nicht einmal (oder zweimal), dann Erfolg, es ist in Ordnung?

+0

Kann jemand erklären, wie man das gleiche mit Jmockito erreichen – Bharat

Antwort

130

Von the docs:

Manchmal müssen wir mit unterschiedlicher Rückgabewert/Ausnahme für den gleichen Methodenaufruf Stummel. Ein typischer Anwendungsfall könnte Mocking-Iteratoren sein. Originalversion von Mockito hatte diese Funktion nicht, um einfaches Spott zu fördern. Zum Beispiel könnte man anstelle von Iteratoren Iterable oder einfach Collections verwenden. Diese bieten natürliche Arten des Stubbing (z. B. mit echten Sammlungen). In seltenen Szenarien aufeinander folgende Aufrufe stubbing nützlich sein könnte, aber:

when(mock.someMethod("some arg")) 
    .thenThrow(new RuntimeException()) 
    .thenReturn("foo"); 

//First call: throws runtime exception: 
mock.someMethod("some arg"); 

//Second call: prints "foo" 
System.out.println(mock.someMethod("some arg")); 

Also in Ihrem Fall, Sie wollen würden:

when(myMock.doTheCall()) 
    .thenReturn("You failed") 
    .thenReturn("Success"); 
+0

Hey, das ist genial, dank Jon. – vikingsteve

+9

Dies hat mich in die richtige Richtung (Danke) für mein Szenario geführt, das sich mit void Methoden beschäftigt - in diesem Fall müssen Sie den alternativen Stil verwenden ... 'doThrow (new RuntimeException()). DoNothing(). When (myMock) .doTheCall(); ' – haggisandchips

18

Der kürzeste Weg zu schreiben, was Sie wollen, ist

when(myMock.doTheCall()).thenReturn("Success", "you failed"); 

Wenn Sie so viele Argumente an thenReturn übergeben, wird jedes Argument höchstens einmal verwendet, mit Ausnahme des allerletzten Arguments w das wird so oft wie nötig verwendet. Wenn Sie zum Beispiel in diesem Fall viermal anrufen, erhalten Sie "Erfolg", "Sie haben versagt", "Sie haben versagt", "Sie haben versagt".

6

Da der Kommentar, der sich darauf bezieht, schwer zu lesen ist. Ich füge eine formatierte Antwort hinzu.

Wenn Sie dies mit einer Void-Funktion versuchen. Wo möchten Sie vielleicht eine Ausnahme als kein Verhalten. Dann würden Sie so etwas tun:

Mockito.doThrow(new Exception("MESSAGE")) 
      .doNothing() 
      .when(mockService).method(eq()); 
0

Um auf this und this Antwort hinzufügen, können Sie auch eine Schleife Kette verwenden, um die verspottete Anrufe. Dies ist nützlich, wenn Sie das gleiche mehrmals maskieren oder in einem Muster nachahmen müssen.

Eg (wenn auch weit hergeholt eins):

import org.mockito.stubbing.Stubber; 

Stubber stubber = doThrow(new Exception("Exception!")); 
for (int i=0; i<10; i++) { 
    if (i%2 == 0) { 
     stubber.doNothing(); 
    } else { 
     stubber.doThrow(new Exception("Exception")); 
    } 
} 
stubber.when(myMockObject).someMethod(anyString());