This following blog post was inspired by Use JUnit’s expected exceptions sparingly. Instead of telling you what you should or should not do let’s try to offer different approaches to test driving exceptions.
As an example for why we need to test exceptions we use the fabulous TDD Kata String Calculator by Roy Osherove. It states:
Calling Add with a negative number will throw an exception “negatives not allowed” - and the negative that was passed.if there are multiple negatives, show all of them in the exception message
Using the annotation based approach the test could look as follows
The above is fine if we do not care what message the exception uses. Maybe we only use exceptions with descriptive names or don’t test the contents of the error message at all, because if you change the content your test will break. Making it subject to change and thus brittle. The same is valid for checking if a button states Sign up
or Create account
. We’re probably be better off testing if the button is invoking the desired functionality instead of its wording.
Nevertheless, since the Kata requires us to show all the passed negative numbers in the exception message we need another approach.
The following is probably the most common approach of testing exceptions
It’s considered verbose and having the fail();
adds extra complexity. The fail();
is necessary to have a failing test, in case the exception is never thrown, as all the assertions are inside of the catch
block. Using the structure above in multiple locations also leads to heavy code duplication.
JUnit5, which is, at the time of this writing, in it’s alpha stage. It provides the following
We can already use the above without adding any extra dependency by using the following helper functions
AssertJ offers fluent assertions, which means the assertions read like English sentences.
Personally I prefer AssertJ due to its fluency. Use what you and your team likes or agrees on. Now you know some of the possibilities.