Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE

1. Introduction

In this quick tutorial, we’ll be looking at how to test if an exception was thrown using the JUnit library.

We will, of course, make sure to cover both the JUnit 4 and JUnit 5 versions.

Further reading:

AssertJ Exception Assertions

Learn how to use AssertJ for performing assertions on exceptions.

Assertions in JUnit 4 and JUnit 5

A look at assertions in both JUnit 4 and 5.

Mocking Exception Throwing using Mockito

Learn to configure a method call to throw an exception in Mockito.

2. JUnit 5

JUnit 5 Jupiter assertions API introduces the assertThrows method for asserting exceptions.

This takes the type of the expected exception and an Executable functional interface where we can pass the code under test through a lambda expression:

@Test
public void whenExceptionThrown_thenAssertionSucceeds() {
    Exception exception = assertThrows(NumberFormatException.class, () -> {
        Integer.parseInt("1a");
    });

    String expectedMessage = "For input string";
    String actualMessage = exception.getMessage();

    assertTrue(actualMessage.contains(expectedMessage));
}

If the expected exception is thrown, assertThrows returns the exception, which enables us to also assert on the message.

Furthermore, it’s important to note that this assertion is satisfied when the enclosed code throws an exception of type NumberFormatException or any of its derived types.

This means that if we pass Exception as the expected exception type, any exception thrown will make the assertion succeed since Exception is the super-type for all exceptions.

If we change the test above to expect a RuntimeException, this will also pass:

@Test
public void whenDerivedExceptionThrown_thenAssertionSucceeds() {
    Exception exception = assertThrows(RuntimeException.class, () -> {
        Integer.parseInt("1a");
    });

    String expectedMessage = "For input string";
    String actualMessage = exception.getMessage();

    assertTrue(actualMessage.contains(expectedMessage));
}

The assertThrows() method enables more fine-grained control for exception assertion logic because we can use it around specific parts of the code.

3. JUnit 4

When using JUnit 4, we can simply use the expected attribute of the @Test annotation to declare that we expect an exception to be thrown anywhere in the annotated test method.

As a result, when the test is run, it will fail if the specified exception isn’t thrown and will pass if it’s thrown:

@Test(expected = NullPointerException.class)
public void whenExceptionThrown_thenExpectationSatisfied() {
    String test = null;
    test.length();
}

In this example, we’ve declared that we’re expecting our test code to result in a NullPointerException.

This is enough if we’re only interested in asserting that an exception is thrown.

When we need to verify some other properties of the exception, we can use the ExpectedException rule.

Let’s see an example of verifying the message property of an exception:

@Rule
public ExpectedException exceptionRule = ExpectedException.none();

@Test
public void whenExceptionThrown_thenRuleIsApplied() {
    exceptionRule.expect(NumberFormatException.class);
    exceptionRule.expectMessage("For input string");
    Integer.parseInt("1a");
}

In the example above, we’re first declaring the ExpectedException rule. Then in our test, we’re asserting that the code that attempts to parse an Integer value will result in a NumberFormatException with the message “For input string”.

4. Conclusion

In this article, we covered asserting exceptions with both JUnit 4 and JUnit 5.

The full source code for the examples is available over on GitHub.

Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE
res – REST with Spring (eBook) (everywhere)
Comments are closed on this article!