2010-09-21 9 views
75

Ich versuche eines meiner verspotteten Objekte eine geprüfte Exception werfen zu lassen, wenn eine bestimmte Methode aufgerufen wird. Ich versuche Folgendes.throw checked Ausnahmen von Mocks mit 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 { 
} 

Das erzeugt jedoch den folgenden Fehler.

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 

Mit Blick auf den Mockito documentation, sie RuntimeException nur verwenden, ist es nicht möglich, mit Mockito geprüft Ausnahmen von einem Mock-Objekt zu werfen?

Antwort

115

Überprüfen Sie die Java API für List. Die Methode get (int) deklariert nur die IndexOutOfBoundException, die RuntimeException erweitert. Sie versuchen, Mockito eine Ausnahme zuzuweisen, die nicht durch diesen bestimmten Methodenaufruf ausgelöst werden kann.

Um weiter zu klären. Die List-Schnittstelle bietet keine überprüfte Ausnahme, die von der get() -Methode ausgelöst wird, und deshalb schlägt Mockito fehl. Wenn Sie die Mock-Liste erstellen, verwendet Mockito die Definition von List.class, um seine Mock zu erstellen. Das Verhalten, das Sie mit der when(list.get(0)).thenThrow(new SomeException()) angeben, stimmt nicht mit der Methodensignatur in List.class überein, sodass Mockito fehlschlägt. Wenn Sie das wirklich wollen, dann lassen Sie Mockito eine new RunTimeException() werfen oder besser noch eine new ArrayIndexOutOfBoundsException() werfen, da die API angibt, dass dies die einzige gültige Ausnahme ist, die ausgelöst wird.

+0

Während mein realer Code nicht wirklich List verwendete, gilt Ihre Antwort auch für diesen Methodenaufruf. Ich habe mich über die falsche Methode lustig gemacht. Vielen Dank. –

+2

extra: Mocktio wird sich nicht beschweren, wenn du eine Methode ohne irgendwelche Throwables machst, aber du bekommst auch diese Ausnahme – dwana

+1

Für Kotliners: Kotlin hat keine Ausnahmen überprüft, also kannst du normalerweise (in der Funktionssignatur) diese Funktion nicht deklarieren löst eine Ausnahme aus. Sie können die Funktion jedoch mit der Anmerkung "Würfe" annotieren, damit der Compiler den gleichen Bytecode generiert, der die Würfe im entsprechenden Java-Code deklariert. Weitere Informationen finden Sie [hier] (https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-throws/index.html). – Metallica

2

Eine Problemumgehung besteht darin, eine willAnswer() Methode zu verwenden.

Zum Beispiel die folgenden Werke (und nicht werfen ein MockitoException sondern wirft tatsächlich ein getestetes Exception wie hier erforderlich) mit BDDMockito:

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

Das Äquivalent für Normal Mockito würde die doAnswer Methode

verwenden