ExpectedException
funktioniert, indem Sie Ihre gesamte Testmethode über eine JUnit @Rule in einen Try-Catch-Block einschließen . Wenn Ihr Code eine Ausnahme auslöst, geht er den Stapel zum nächsten try / catch hoch, der sich zufällig in der ExpectedException-Instanz befindet (die überprüft, ob es sich um die erwartete Ausnahme handelt).
Wenn in Java eine nicht erfasste Ausnahme in einer Methode auftritt, kehrt das Steuerelement später in dieser Methode niemals zu Anweisungen zurück. Hier gelten die gleichen Regeln: Control kehrt nach der Ausnahme nie mehr zu den Anweisungen in Ihrem Test zurück.
Technisch gesehen könnten Sie die Überprüfungen in einen endgültigen Block setzen, aber das ist in der Regel eine schlechte Angewohnheit . BEARBEITEN: Ihr zu testendes System löst möglicherweise eine unerwartete oder gar keine Ausnahme aus, die Ihnen eine hilfreiche Fehlermeldung und Ablaufverfolgung liefert. Wenn dieser Fehler jedoch dazu führt, dass Ihre Überprüfungen oder Zusicherungen im finally
Block fehlschlagen , zeigt Java dies anstelle einer Meldung über die unerwartete Ausnahme oder den unerwarteten Erfolg an. Dies kann das Debuggen erschweren, insbesondere weil Ihr Fehler aus Codezeilen stammt, die der Grundursache des Fehlers folgen, was fälschlicherweise bedeutet, dass der darüber liegende Code erfolgreich war.
Wenn Sie den Status nach der Ausnahme wirklich pro Methode überprüfen müssen, können Sie jederzeit zu dieser Redewendung zurückkehren:
@Test
public void testExpectedException()
{
MockedObject mockObj = mock(MockedObj.class);
MySubject subject = new MySubject(mockedObj);
try {
subject.someMethodThrowingException();
fail("Expected MyException.");
} catch (MyException expected) {
assertEquals("My exception message.", expected.getMessage());
}
verify(mockObj).someCleanup(eq(...));
}
Update: Mit den Lambda-Ausdrücken von Java 8 können Sie einen Funktionsschnittstellenaufruf so kurz in einen try-Block einbinden, dass er nützlich ist . Ich kann mir vorstellen, dass die Unterstützung dieser Syntax in viele Standardtestbibliotheken Eingang findet.
assertThrows(MyException.class,
() -> systemUnderTest.throwingMethod());
finally
Block die Ausnahme verschlucken?finally
fängt die Ausnahme nicht ab, daher wird sie an den Wrapper weitergegeben. Siehe Kevin Welkers Antwort; das funktioniert gut.