ExpectedException
works by wrapping your entire test method in a try-catch block via a JUnit @Rule. When your code throws an exception, it goes up the stack to the nearest try/catch, which happens to be in the ExpectedException instance (which checks that it is the exception you're expecting).
In Java, if an uncaught exception occurs in a method, control will never return to statements later in that method. The same rules apply here: Control never returns to the statements in your test after the exception.
Technically, you could put the verifications in a finally block, but that tends to be a bad habit. EDIT: Your system-under-test might throw an unexpected exception, or no exception at all, which would give you a helpful failure message and trace; however, if that failure then causes your verifications or assertions to fail in the finally
block, then Java will show that rather than a message about the unexpected exception or unexpected success. This can make debugging difficult, especially because your error will come from lines of code following the root cause of the error, incorrectly implying that the code above it succeeded.
If you really need to verify state after the exception, on a per-method basis, you can always revert back to this idiom:
@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: With Java 8's lambda expressions, you can wrap a functional interface call in a try block concisely enough to be useful. I imagine support for this syntax will find its way into many standard testing libraries.
assertThrows(MyException.class,
() -> systemUnderTest.throwingMethod());
finally
block swallow the exception?finally
doesn't catch the exception, so it will be propagated to the wrapper. See Kevin Welker's answer; this works just fine. – Withy