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:

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:

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.

@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:

@Test public void failsWhenNoExceptionIsThrown() { assertThatThrownBy(() -> System.out.println()); }

The message is:

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:

@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

Popular posts from this blog

macOS: Insert current date shortcut with `Shortcuts.app`

Parameterized tests in JavaScript with Jest