What’s the best way to handle expected exceptions in JUnit?
If you want to inspect the contents of the exception and make assertions against it then there is only one clean way; Use the ExpectedException JUnit Rule.
I’ve seen it used badly, though. Think about how to name the field. I see no better name than simply “thrown”. When you use it in your tests it reads perfectly sensibly as
thrown.expect(this)
whereas
expectedException.expect(that)
is a bit clumsy, and
e.expect(theOther)
is not expressive.
The other mistake people make is to not tidy things up with reusable custom Hamcrest matchers. They’re so easy to create (a future post on that issue coming soon), for your common domain-specific exceptions they can be easily reused, and they make the code expressive and simple. You can simply use any Matcher<?>.
One of the simplest options is to use the Hamcrest “hasProperty” matcher to assert against properties of the exception.
@Rule public ExpectedException thrown = ExpectedException.none(); @Test public void shouldGoWrongSometimes() throws Exception { thrown.expect(SomeException.class); thrown.expectMessage("That was bad input"); thrown.expect(isOurSpecialExceptionType()); thrown.expect(hasProperty("xyz", equalTo("oh dear"))); testSubject.use("bad data"); }
Leave a Reply