What if your tests could catch the exact error type every time without fail?
Why Checking exception type hierarchy in JUnit? - Purpose & Use Cases
Imagine you have a big program that can throw many types of errors. You want to check if the program throws the right kind of error when something goes wrong. Doing this by running the program and watching for errors manually is like trying to catch a tiny fish with your bare hands in a big river.
Manually checking errors is slow and easy to miss. You might see an error but not know if it is the exact type you expect or just a related one. This can cause confusion and bugs to slip through. Also, repeating these checks by hand every time you change code wastes a lot of time.
Using JUnit to check exception type hierarchy lets you write clear tests that automatically verify if the thrown error is exactly the one you expect or a subtype. This saves time, reduces mistakes, and makes your tests reliable and easy to run again and again.
try { methodThatThrows(); fail("Expected exception"); } catch (Exception e) { if (!(e instanceof SpecificException)) { fail("Wrong exception type"); } }
assertThrows(SpecificException.class, () -> methodThatThrows());You can confidently ensure your program throws the right errors, improving code quality and catching bugs early.
When building a banking app, you want to check that withdrawing too much money throws an OverdraftException, not just any error. This test helps catch mistakes before customers see them.
Manual error checks are slow and error-prone.
JUnit's exception hierarchy checks automate and simplify this process.
This leads to more reliable and maintainable tests.
Practice
Solution
Step 1: Understand the purpose of assertThrows()
assertThrows() is designed to check if a block of code throws an exception of a specified type or its subclass.Step 2: Compare with other assertions
assertEquals() checks equality, assertTrue() checks boolean conditions, and assertNull() checks for null values, none of which check exceptions.Final Answer:
assertThrows() -> Option AQuick Check:
Exception type check = assertThrows() [OK]
- Using assertEquals() to check exceptions
- Confusing assertTrue() with exception checks
- Expecting assertNull() to verify exceptions
Solution
Step 1: Recall assertThrows() method signature
assertThrows() takes the exception class as the first argument and a lambda expression as the second.Step 2: Match the syntax
assertThrows(NullPointerException.class, () -> method()); correctly uses assertThrows(NullPointerException.class, () -> method()); which matches the required syntax.Final Answer:
assertThrows(NullPointerException.class, () -> method()); -> Option AQuick Check:
Correct syntax = assertThrows(NullPointerException.class, () -> method()); [OK]
- Passing exception instance instead of class
- Swapping argument order in assertThrows()
- Not using lambda expression for the executable
assertThrows(RuntimeException.class, () -> { throw new IllegalArgumentException(); });What will be the result of this test?
Solution
Step 1: Check exception hierarchy
IllegalArgumentException extends RuntimeException, so it is a subclass.Step 2: Understand assertThrows behavior
assertThrows(RuntimeException.class, ...) passes if the thrown exception is RuntimeException or any subclass.Final Answer:
Test passes because IllegalArgumentException is a subclass of RuntimeException -> Option CQuick Check:
Subclass exception passes assertThrows superclass check [OK]
- Thinking exact exception type is required
- Confusing subclass with unrelated exceptions
- Expecting compilation error for subclass exceptions
assertThrows(RuntimeException.class, () -> { throw new FileNotFoundException(); });The test fails. What is the most likely reason?
Solution
Step 1: Check exception hierarchy
FileNotFoundException extends IOException, not RuntimeException.Step 2: Understand assertThrows behavior
assertThrows(RuntimeException.class, ...) fails because the thrown exception is not RuntimeException or any subclass. Other options are incorrect: checked exceptions like FileNotFoundException do not require declaration in the test method when using Executable lambdas.Final Answer:
FileNotFoundException is not a subclass of RuntimeException -> Option DQuick Check:
Non-subclass exception causes assertThrows to fail [OK]
- Misidentifying exception subclass relationships
- Ignoring checked exception declaration rules
- Expecting runtime exceptions to behave like checked
Solution
Step 1: Understand assertThrows behavior with superclass
assertThrows(IOException.class, ...) passes if the thrown exception is IOException or any subclass.Step 2: Evaluate other options
Use assertThrows(Exception.class, () -> method()); and check instance with instanceof IOException requires manual checks and complicates test; Use try-catch inside test and assert exception type manually is verbose; Use assertThrows(Throwable.class, () -> method()); is too broad and accepts all throwables.Final Answer:
Use assertThrows(IOException.class, () -> method()); -> Option BQuick Check:
Superclass in assertThrows covers subclasses [OK]
- Using too broad exception classes
- Manually checking exception types unnecessarily
- Ignoring assertThrows built-in subclass support
Ready to prove it?
Pass the test and this pattern moves unknown
