2012-08-02 11 views
58

Desidero utilizzare Mockito per verificare il codice (semplificato) riportato di seguito. Non so come dire a Mockito di fallire la prima volta, poi ci riesco la seconda volta.Simula l'interruzione della prima chiamata, la seconda chiamata ha esito positivo

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(); 
    } 
} 

posso installare il test successo con:

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

E la prova di fallimento con:

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

Ma come faccio a verificare che se non riesce una volta (o due volte), poi succede, va bene?

+0

Può uno spiegare come ottenere lo stesso utilizzando Jmockito – Bharat

risposta

130

Da the docs:

volte abbiamo bisogno di stub con diversi valore di ritorno/eccezione per la stessa chiamata di metodo. Il tipico caso d'uso potrebbe essere un derisione degli iteratori. La versione originale di Mockito non aveva questa funzione per promuovere il mocking semplice. Ad esempio, al posto di iteratori si potrebbe usare Iterable o semplicemente collezioni. Quelli offrono modi naturali di soppressione (ad esempio utilizzando raccolte reali). In scenari rari spegnendo chiamate consecutive potrebbe essere utile, però:

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")); 

Quindi nel tuo caso, che ci si vuole:

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

Ehi, che è impressionante, grazie Jon. – vikingsteve

+9

Questo mi ha indirizzato nella giusta direzione (grazie) per il mio scenario che si occupava di metodi void: in questo caso è necessario utilizzare lo stile alternativo ... 'doThrow (new RuntimeException()). DoNothing(). When (myMock) .doTheCall(); ' – haggisandchips

18

La via più breve per scrivere quello che vuoi è

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

Quando si forniscono argomenti con più elementi a thenReturn in questo modo, ciascun argomento verrà utilizzato al massimo una volta, eccetto per l'ultimo argomento, w che viene usato tutte le volte che è necessario. Ad esempio, in questo caso, se si effettua la chiamata 4 volte, si otterrà "Success", "you failed", "you failed", "you failed".

6

Poiché il commento relativo a questo è difficile da leggere. Aggiungerò una risposta formattata.

Se si sta tentando di eseguire questa operazione con una funzione di annullamento. Dove potresti desiderare un'eccezione che nessun comportamento. Poi si dovrebbe fare qualcosa di simile:

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

Per aggiungere a this e this risposta, è anche possibile utilizzare un ciclo per la catena delle chiamate deriso. Questo è utile se hai bisogno di prendere in giro la stessa cosa più volte o di deridere in qualche schema.

Eg (anche se molto peregrina):

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()); 
Problemi correlati