assertThrows JUnit 5 Exception Testing | Java Fresher
Fast recall
Quick revision
Core answer
assertThrowsExactly for exact runtime type.Interview-ready guide
Interview answer
assertThrows runs the supplied lambda and fails when it completes normally or throws an incompatible type. A subtype satisfies assertThrows; when exact runtime type is part of the contract, JUnit also has assertThrowsExactly. The successful assertion returns the caught exception, so I can inspect a stable error code, message fragment, custom field, or cause when that detail is public behavior. For example, I can assert that account.withdraw(-10) throws IllegalArgumentException and carries the code NEGATIVE_AMOUNT. I keep setup outside the lambda so another call cannot accidentally satisfy the assertion. A hand-written try/catch can be valid, but assertThrows is clearer for this common contract and avoids forgetting a fail() on the normal path.
assertThrows JUnit 5 Exception Testing | Java Fresher
Direct Answer
assertThrows(ExpectedType.class, executable) runs the executable, passes for the expected type or a subtype, and returns the exception. Keep the executable limited to the operation expected to fail. Inspect a stable message, code, field, or cause only when that detail belongs to the contract; use assertThrowsExactly for exact runtime type.
Deep Dive & Architecture
assertThrows tests an exception as an observable result. JUnit runs only the executable passed to it. The assertion fails when that code completes normally or throws an incompatible type; when it succeeds, it returns the caught exception for further checks.
For example, assertThrows(IllegalArgumentException.class, () -> account.withdraw(-10)) proves the invalid call is rejected. The returned exception can then be checked for a stable message, cause, or domain field. Keep the lambda limited to the one operation expected to fail, because setup code inside the lambda could throw the same type and make a weak test pass. Prefer the most specific exception that forms part of the method contract.
Common Mistakes & Pitfalls
- try/catch without a failing normal path. If nothing throws, the test can pass accidentally;
assertThrowsavoids that pattern. - Asserting a broad superclass. Use the most specific exception promised by the contract.
- Checking unstable details. Assert a message, code, cause, or field only when it is stable public behavior.
- Too much in the lambda. Setup inside the executable can throw the same type and satisfy a weak assertion.
Check your understanding
Answer these without looking back at the article.
- What is the Arrange-Act-Assert (AAA) pattern in unit testing?
- How do you test floating point numbers in JUnit 5?
- How do you verify that a list returned by a method has the correct content in JUnit 5?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.