Test Exception JUnit 5 Java | Fresher Interview
Fast recall
Quick revision
Core answer
assertThrowsExactly when exact runtime type matters.Interview-ready guide
Interview answer
In JUnit 5 I test exceptions with assertThrows. I give it the exception class I expect and a lambda that wraps the call that should throw. If the code doesn't throw, or throws the wrong type, the test fails. The really useful part is that on success assertThrows returns the exception object, so I can then assert on its message or its cause.
That's a big improvement over the old JUnit 4 way, which was the Test annotation with expected equals the exception class. That style only checked the type — it couldn't look at the message, and it couldn't tell you which line in the method actually threw, so any statement throwing that type would make the test pass for the wrong reason.
So a good exception test does two things: it confirms the right type was thrown, and it checks the message is what I expect. For example, I'd capture the exception from assertThrows when I divide by zero, and then assertEquals that the message is divisor must not be zero. I keep the lambda small — only the call that should throw goes inside — so the assertion proves that specific line threw. There's also assertDoesNotThrow for the negative case, where I want to prove a valid input runs cleanly.
Common mistakes are using try-catch with a fail call, which is verbose and easy to get wrong, and asserting on a broad superclass like Exception, which passes for almost anything.
Test Exception JUnit 5 Java | Fresher Interview
Direct Answer
In JUnit Jupiter, assertThrows(ExpectedType.class, executable) passes when the executable throws that type or a subtype and returns the exception. Keep the executable small and inspect a stable message, code, field, or cause only when it is part of the contract. Use assertThrowsExactly when exact runtime type matters.
Deep Dive & Architecture
JUnit 5 treats an expected exception as a normal assertion result. assertThrows runs the supplied lambda and fails if it finishes normally or throws a type outside the expected hierarchy. On success, the returned exception can be inspected like any other object.
For example, var error = assertThrows(IllegalArgumentException.class, () -> calculator.divide(10, 0)); can be followed by an assertion on a stable message or error code. Keep only the operation under test inside the lambda. Expecting a broad type such as Exception weakens the test because many unrelated faults can satisfy it. assertDoesNotThrow covers the opposite contract, where a valid input must complete without an exception.
Common Mistakes & Pitfalls
- try/catch + fail(). It can work, but forgetting
fail()on the normal path creates a false pass;assertThrowsexpresses the contract directly. - Checking unstable text. Verify a message, code, cause, or field only when that detail belongs to the public behavior.
- Wrapping too much in the lambda. Put only the operation expected to throw inside, so setup cannot satisfy the assertion accidentally.
- Asserting a broad superclass. Prefer the most specific exception type promised by the method; use
assertThrowsExactlyonly when exact runtime type matters.
Check your understanding
Answer these without looking back at the article.
- What is JUnit 5 and how do you write a basic test?
- What are the most important JUnit 5 annotations?
- How do you use assertions in JUnit 5?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.