How do you test expected exceptions in JUnit?

Testing expected exceptions in JUnit means asserting that a specific piece of code throws the exception you expect, rather than letting an uncaught exception simply fail the test for the wrong reason.

Key Points: • JUnit 4 supports @Test(expected = IllegalArgumentException.class), which passes only if that exact exception type is thrown. • JUnit 5 replaces this with assertThrows(IllegalArgumentException.class, () -> { ... }), which also returns the thrown exception for further assertions. • assertThrows() is more precise because it scopes the expectation to a specific line, whereas @Test(expected=...) allows the exception from anywhere in the method. • You can assert on the exception's message or cause after catching it via assertThrows()'s return value. • Testing for exceptions confirms that invalid input or failure conditions are properly rejected by the code under test.

Example: For a method that validates a non-negative deposit amount, assertThrows(IllegalArgumentException.class, () -> account.deposit(-5)) confirms a negative deposit correctly throws.

Code Example:

@Test
void rejectsNegativeDeposit() {
    IllegalArgumentException ex = assertThrows(
        IllegalArgumentException.class,
        () -> account.deposit(-5));

    assertEquals("Amount must be positive", ex.getMessage());
}

Interview Tip: A concise interview answer is:

"In JUnit 5 I use assertThrows(ExceptionType.class, () -> code) to assert a specific block throws the expected exception, and I can inspect the returned exception's message afterward. It's more precise than JUnit 4's @Test(expected=...) because it scopes the expectation to one exact call."