JUnit 5
Exception Handling
Unit Testing
Software Development
Java Programming

JUnit 5 How to assert an exception is thrown?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

JUnit 5 brings a modern approach to testing in Java, with a special focus on testing exceptions. Ensuring that your code not only runs successfully but also fails correctly under adverse conditions is a critical part of robust software development. This aspect of testing is dealt with in JUnit 5 using assertions that an exception is expected to be thrown.

Exception Testing in JUnit 5

Unlike JUnit 4, which used the @Test(expected = Exception.class) annotation, JUnit 5 introduces more powerful and flexible mechanisms for exception handling through its Assertions class. Specifically, JUnit 5 provides the assertThrows() method, which allows for the assertion that a particular type of exception is thrown and also enables the testing of the exception's message and other properties.

Using assertThrows()

The assertThrows() method is a part of the JUnit 5 Assertions API. It is used to assert that execution of a particular piece of code results in a specific type of exception. This method is not only more expressive than the old @Test(expected = ...) annotation but also allows for more controlled and granular exception testing.

How to Use assertThrows()

Here is the general syntax of the assertThrows() method:

java
Throwable exception = assertThrows(ExpectedExceptionType.class, executable);
  • ExpectedExceptionType.class is the type of the exception you expect the executable to throw.
  • executable is a lambda expression or a method reference that executes the code under test.

Example

Consider you have a method that divides two numbers:

java
1public class Calculator {
2    public int divide(int numerator, int denominator) {
3        if (denominator == 0) {
4            throw new ArithmeticException("Division by zero");
5        }
6        return numerator / denominator;
7    }
8}

To test that the divide method throws an ArithmeticException when the denominator is zero, you would write:

java
1import static org.junit.jupiter.api.Assertions.assertThrows;
2
3class CalculatorTest {
4
5    @Test
6    void testDivisionByZeroThrowsException() {
7        Calculator calculator = new Calculator();
8        
9        Exception exception = assertThrows(ArithmeticException.class, () -> {
10            calculator.divide(1, 0);
11        });
12
13        assertEquals("Division by zero", exception.getMessage());
14    }
15}

Advantages of assertThrows()

Using assertThrows() provides several benefits:

  • Clarity and Expressiveness: It makes it explicitly clear what type of exception is expected.
  • Access to the Exception Object: It allows further assertions on the thrown exception, such as validating the exception's message.
  • Improved Readability: It simplifies understanding what part of the code is under test compared to older techniques.

Best Practices

  • Specificity in Exception Types: Always assert specific exception types rather than general ones to avoid masking bugs.
  • Message Assertion: Where applicable, assert the exception message to ensure that your code not only throws the correct type of exception but also provides the correct context through its message.

Summary Table

MethodDescriptionUsage
assertThrows()Asserts that the executable throws a specific type of exception.assertThrows(ExceptionType.class, () -> { codeThatThrows(); })
getMessage()Retrieves the message from the thrown exception.Used after assertThrows() to check the error message for accuracy.

Conclusion

Testing for exceptions is an integral part of building reliable applications. JUnit 5's assertThrows() method provides a robust framework for such tests, ensuring that applications behave correctly under erroneous conditions and helping developers write cleaner, more efficient tests.


Course illustration
Course illustration

All Rights Reserved.