JUnit: Testing Exceptions with Java 8 and AssertJ 3.0.0
AssertJ 3.0.0 release for Java 8 makes testing exceptions much easier than before. In one of my previous blog post I described how to utilize plain Java 8 to achieve this, but with AssertJ 3.0.0 much of the code I created may be removed.
Warning: this blog post contains mostly the code examples.
SUT – System Under Test
We will test exceptions thrown by the below 2 classes.
The first one:
01 02 03 04 05 06 07 08 09 10 | class DummyService { public void someMethod() { throw new RuntimeException( "Runtime exception occurred" ); } public void someOtherMethod( boolean b) { throw new RuntimeException( "Runtime exception occurred" , new IllegalStateException( "Illegal state" )); } } |
And the second:
1 2 3 4 5 6 7 8 9 | class DummyService2 { public DummyService2() throws Exception { throw new Exception( "Constructor exception occurred" ); } public DummyService2( boolean dummyParam) throws Exception { throw new Exception( "Constructor exception occurred" ); } } |
assertThatThrownBy() examples
Note: static import of org.assertj.core.api.Assertions.assertThatThrownBy
is required in order to make the below code work properly.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | @Test public void verifiesTypeAndMessage() { assertThatThrownBy( new DummyService()::someMethod) .isInstanceOf(RuntimeException. class ) .hasMessage( "Runtime exception occurred" ) .hasNoCause(); } @Test public void verifiesCauseType() { assertThatThrownBy(() -> new DummyService().someOtherMethod( true )) .isInstanceOf(RuntimeException. class ) .hasMessage( "Runtime exception occurred" ) .hasCauseInstanceOf(IllegalStateException. class ); } @Test public void verifiesCheckedExceptionThrownByDefaultConstructor() { assertThatThrownBy(DummyService2:: new ) .isInstanceOf(Exception. class ) .hasMessage( "Constructor exception occurred" ); } @Test public void verifiesCheckedExceptionThrownConstructor() { assertThatThrownBy(() -> new DummyService2( true )) .isInstanceOf(Exception. class ) .hasMessage( "Constructor exception occurred" ); } |
The assertions presented comes from AbstractThrowableAssert
and there are much more of them for you to use!
No exception thrown!
The below test will fail as no exception is thrown:
1 2 3 4 | @Test public void failsWhenNoExceptionIsThrown() { assertThatThrownBy(() -> System.out.println()); } |
The message is:
1 | java.lang.AssertionError: Expecting code to raise a throwable. |
AAA Style
If you wish to distinguish act and assert phases of the test for improving readability, it is also possible:
01 02 03 04 05 06 07 08 09 10 11 12 13 | @Test public void aaaStyle() { // arrange DummyService dummyService = new DummyService(); // act Throwable throwable = catchThrowable(dummyService::someMethod); // assert assertThat(throwable) .isNotNull() .hasMessage( "Runtime exception occurred" ); } |
References
- Source code for this article is available on GitHub (have a look at
com.github.kolorobot.assertj.exceptions
package) - AssertJ 3.0.0 for Java 8 release
Reference: | JUnit: Testing Exceptions with Java 8 and AssertJ 3.0.0 from our JCG partner Rafal Borowiec at the Codeleak.pl blog. |