1. Overview
In this quick tutorial, we’ll have a look at AssertJ’s exception-dedicated assertions.
2. Without AssertJ
In order to test if an exception was thrown, we’d need to catch the exception and then perform assertions:
try { // ... } catch (Exception e) { // assertions }
But, what if an exception isn’t thrown? In that case, the test would pass; this is why it’s necessary to fail test cases manually.
3. With AssertJ
Using Java 8, we can do assertions on exceptions easily, by leveraging AssertJ and lambda expressions.
3.1. Using assertThatThrownBy()
Let’s check if indexing an out of bounds item in a list raises an IndexOutOfBoundsException:
assertThatThrownBy(() -> { List<String> list = Arrays.asList("String one", "String two")); list(2); }).isInstanceOf(IndexOutOfBoundsException.class) .hasMessageContaining("Index: 2, Size: 2");
Notice how the code fragment that might throw an exception gets passed as a lambda expression.
Of course, we can leverage various standard AssertJ assertions here like:
.hasMessage("Index: %s, Size: %s", 2, 2) .hasMessageStartingWith("Index: 2") .hasMessageContaining("2") .hasMessageEndingWith("Size: 2") .hasMessageMatching("Index: \\d+, Size: \\d+") .hasCauseInstanceOf(IOException.class) .hasStackTraceContaining("java.io.IOException");
3.2. Using assertThatExceptionOfType
The idea is similar to the example above, but we can specify the exception type at the beginning:
assertThatExceptionOfType(IndexOutOfBoundsException.class) .isThrownBy(() -> { // ... }).hasMessageMatching("Index: \\d+, Size: \\d+");
3.3. Using assertThatIOException and Other Common Types
AssertJ provides wrappers for common exception types like:
assertThatIOException().isThrownBy(() -> { // ... });
And similarly:
- assertThatIllegalArgumentException()
- assertThatIllegalStateException()
- assertThatIOException()
- assertThatNullPointerException()
3.4. Separating the Exception From the Assertion
An alternative way to write our unit tests is writing the when and then logic in separate sections:
// when Throwable thrown = catchThrowable(() -> { // ... }); // then assertThat(thrown) .isInstanceOf(ArithmeticException.class) .hasMessageContaining("/ by zero");
4. Conclusion
And there we are. In this short article, we discussed different ways to use AssertJ for performing assertions on exceptions.
As always, the code relating to this article is available over on Github.