There is a newer version available.
For the latest stable version, please use JUnit 6.0.1!

Exception Handling

JUnit Jupiter provides robust support for handling test exceptions. This includes the built-in mechanisms for managing test failures due to exceptions, the role of exceptions in implementing assertions and assumptions, and how to specifically assert non-throwing conditions in code.

Uncaught Exceptions

In JUnit Jupiter, if an exception is thrown from a test method, a lifecycle method, or an extension and not caught within that test method, lifecycle method, or extension, the framework will mark the test or test class as failed.

Failed assumptions deviate from this general rule.

In contrast to failed assertions, failed assumptions do not result in a test failure; rather, a failed assumption results in a test being aborted.

See Assumptions for further details and examples.

In the following example, the failsDueToUncaughtException() method throws an ArithmeticException. Since the exception is not caught within the test method, JUnit Jupiter will mark the test as failed.

private final Calculator calculator = new Calculator();

@Test
void failsDueToUncaughtException() {
	// The following throws an ArithmeticException due to division by
	// zero, which causes a test failure.
	calculator.divide(1, 0);
}
It’s important to note that specifying a throws clause in the test method has no effect on the outcome of the test. JUnit Jupiter does not interpret a throws clause as an expectation or assertion about what exceptions the test method should throw. A test fails only if an exception is thrown unexpectedly or if an assertion fails.

Failed Assertions

Assertions in JUnit Jupiter are implemented using exceptions. The framework provides a set of assertion methods in the org.junit.jupiter.api.Assertions class, which throw AssertionError when an assertion fails. This mechanism is a core aspect of how JUnit handles assertion failures as exceptions. See the Assertions section for further information about JUnit Jupiter’s assertion support.

Third-party assertion libraries may choose to throw an AssertionError to signal a failed assertion; however, they may also choose to throw different types of exceptions to signal failures. See also: Third-party Assertion Libraries.
JUnit Jupiter itself does not differentiate between failed assertions (AssertionError) and other types of exceptions. All uncaught exceptions lead to a test failure. However, Integrated Development Environments (IDEs) and other tools may distinguish between these two types of failures by checking whether the thrown exception is an instance of AssertionError.

In the following example, the failsDueToUncaughtAssertionError() method throws an AssertionError. Since the exception is not caught within the test method, JUnit Jupiter will mark the test as failed.

private final Calculator calculator = new Calculator();

@Test
void failsDueToUncaughtAssertionError() {
	// The following incorrect assertion will cause a test failure.
	// The expected value should be 2 instead of 99.
	assertEquals(99, calculator.add(1, 1));
}

Asserting Expected Exceptions

JUnit Jupiter offers specialized assertions for testing that specific exceptions are thrown under expected conditions. The assertThrows() and assertThrowsExactly() assertions are critical tools for validating that your code responds correctly to error conditions by throwing the appropriate exceptions.

Using assertThrows()

The assertThrows() method is used to verify that a particular type of exception is thrown during the execution of a provided executable block. It not only checks for the type of the thrown exception but also its subclasses, making it suitable for more generalized exception handling tests. The assertThrows() assertion method returns the thrown exception object to allow performing additional assertions on it.

@Test
void testExpectedExceptionIsThrown() {
	// The following assertion succeeds because the code under assertion
	// throws the expected IllegalArgumentException.
	// The assertion also returns the thrown exception which can be used for
	// further assertions like asserting the exception message.
	IllegalArgumentException exception =
		assertThrows(IllegalArgumentException.class, () -> {
			throw new IllegalArgumentException("expected message");
		});
	assertEquals("expected message", exception.getMessage());

	// The following assertion also succeeds because the code under assertion
	// throws IllegalArgumentException which is a subclass of RuntimeException.
	assertThrows(RuntimeException.class, () -> {
		throw new IllegalArgumentException("expected message");
	});
}

Using assertThrowsExactly()

The assertThrowsExactly() method is used when you need to assert that the exception thrown is exactly of a specific type, not allowing for subclasses of the expected exception type. This is useful when precise exception handling behavior needs to be validated. Similar to assertThrows(), the assertThrowsExactly() assertion method also returns the thrown exception object to allow performing additional assertions on it.

@Test
void testExpectedExceptionIsThrown() {
	// The following assertion succeeds because the code under assertion throws
	// IllegalArgumentException which is exactly equal to the expected type.
	// The assertion also returns the thrown exception which can be used for
	// further assertions like asserting the exception message.
	IllegalArgumentException exception =
		assertThrowsExactly(IllegalArgumentException.class, () -> {
			throw new IllegalArgumentException("expected message");
		});
	assertEquals("expected message", exception.getMessage());

	// The following assertion fails because the assertion expects exactly
	// RuntimeException to be thrown, not subclasses of RuntimeException.
	assertThrowsExactly(RuntimeException.class, () -> {
		throw new IllegalArgumentException("expected message");
	});
}

Asserting That no Exception is Expected

Although any exception thrown from a test method will cause the test to fail, there are certain use cases where it can be beneficial to explicitly assert that an exception is not thrown for a given code block within a test method. The assertDoesNotThrow() assertion can be used when you want to verify that a particular piece of code does not throw any exceptions.

@Test
void testExceptionIsNotThrown() {
	assertDoesNotThrow(() -> {
		shouldNotThrowException();
	});
}

void shouldNotThrowException() {
}
Third-party assertion libraries often provide similar support. For example, AssertJ has assertThatNoException().isThrownBy(() → …​). See also: Third-party Assertion Libraries.