2010-09-21 12 views
75

Sto provando ad avere uno dei miei oggetti derisi lanciare un'eccezione controllata quando viene chiamato un metodo particolare. Sto provando il seguente.throw checked Eccezioni da banchine con Mockito

@Test(expectedExceptions = SomeException.class) 
public void throwCheckedException() { 
    List<String> list = mock(List.class); 
    when(list.get(0)).thenThrow(new SomeException()); 
    String test = list.get(0); 
} 

public class SomeException extends Exception { 
} 

Tuttavia, che produce il seguente errore.

org.testng.TestException: 
Expected exception com.testing.MockitoCheckedExceptions$SomeException but got org.mockito.exceptions.base.MockitoException: 
Checked exception is invalid for this method! 
Invalid: com.testing.MockitoCheckedExceptions$SomeException 

Guardando il Mockito documentation, usano solo RuntimeException, non è possibile lanciare eccezioni controllate da un oggetto fittizio con Mockito?

risposta

115

Controllare l'API Java per List. Il metodo get (int) viene dichiarato per generare solo IndexOutOfBoundException che estende RuntimeException. Stai cercando di dire a Mockito di lanciare un'eccezione che non è valida per essere lanciata da quella particolare chiamata di metodo.

Per ulteriori chiarimenti. L'interfaccia Elenco non prevede il lancio di un'eccezione verificata dal metodo get() ed è per questo motivo che Mockito non funziona. Quando crei l'Elenco deriso, Mockito usa la definizione di List.class per creare il suo mock. Il comportamento che si sta specificando con when(list.get(0)).thenThrow(new SomeException()) non corrisponde alla firma del metodo in List.class, quindi Mockito non riesce. Se vuoi davvero farlo, allora Mockito lancia un new RunTimeException() o ancora meglio lancia un new ArrayIndexOutOfBoundsException() poiché l'API specifica che è l'unica eccezione valida da lanciare.

+0

Mentre il mio codice reale non stava effettivamente usando List, la tua risposta vale anche per quella chiamata di metodo. Stavo prendendo in giro il metodo sbagliato. Grazie. –

+2

extra: Mocktio non si lamenterà se fai un metodo senza alcun oggetto da buttare, ma otterrai anche questa eccezione – dwana

+1

Per Kotliners: Kotlin non ha eccezioni controllate, quindi non puoi normalmente dichiarare (nella firma della funzione) che la funzione lancia un'eccezione Tuttavia, è possibile annotare la funzione con l'annotazione 'Throws' per far sì che il compilatore generi lo stesso bytecode come dichiarazione di lancio nell'equivalente codice Java. Vedi [qui] (https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-throws/index.html) per maggiori dettagli. – Metallica

2

Una soluzione alternativa consiste nell'utilizzare un metodo willAnswer().

Ad esempio, i seguenti lavori (e non gettare un MockitoException ma in realtà getta un controllato Exception come richiesto qui) utilizzando BDDMockito:

given(someObj.someMethod(stringArg1)).willAnswer(invocation -> { throw new Exception("abc msg"); }); 

L'equivalente per la pianura Mockito sarebbe di utilizzare il metodo doAnswer

Problemi correlati