Bird
Raised Fist0
JUnittesting~5 mins

Checking exception type hierarchy in JUnit

Choose your learning style10 modes available
Introduction

We check exception type hierarchy to make sure the right kind of error happens. This helps us catch mistakes early and fix them.

When you want to test if a method throws a specific exception or its subclass.
When you want to ensure your code handles errors correctly in a chain of exceptions.
When you want to verify that a general exception type is thrown instead of a more specific one.
When you want to confirm that your code does not throw unexpected exceptions.
When you want to document expected error behavior in your tests clearly.
Syntax
JUnit
assertThrows(ExpectedException.class, () -> {
    // code that should throw exception
});

assertThrows checks if the code throws the expected exception or any subclass of it.

The first argument is the exception class you expect.

Examples
This test passes because FileNotFoundException is a subclass of IOException.
JUnit
assertThrows(IOException.class, () -> {
    throw new FileNotFoundException();
});
This test passes because NullPointerException is a subclass of RuntimeException.
JUnit
assertThrows(RuntimeException.class, () -> {
    throw new NullPointerException();
});
This test passes because IllegalArgumentException is a subclass of Exception.
JUnit
assertThrows(Exception.class, () -> {
    throw new IllegalArgumentException();
});
This test fails because IllegalArgumentException is NOT a subclass of IOException.
JUnit
assertThrows(IOException.class, () -> {
    throw new IllegalArgumentException();
});
Sample Program

The first test passes because FileNotFoundException is a subclass of IOException. The second test fails because IllegalArgumentException is not related to IOException.

JUnit
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.api.Test;
import java.io.FileNotFoundException;
import java.io.IOException;

public class ExceptionHierarchyTest {

    @Test
    void testFileNotFoundExceptionIsIOException() {
        assertThrows(IOException.class, () -> {
            throw new FileNotFoundException("File missing");
        });
    }

    @Test
    void testIllegalArgumentExceptionIsNotIOException() {
        assertThrows(IOException.class, () -> {
            throw new IllegalArgumentException("Bad argument");
        });
    }
}
OutputSuccess
Important Notes

Use assertThrows to check exception types and their subclasses easily.

If the thrown exception is not the expected type or subclass, the test fails with a clear message.

This helps catch errors early and documents expected error behavior in your tests.

Summary

assertThrows checks if code throws an expected exception or its subclass.

Tests pass if the thrown exception matches or inherits from the expected type.

Tests fail if a different exception type is thrown.

Practice

(1/5)
1. In JUnit, when you want to check if a method throws an exception of a specific type or any of its subclasses, which assertion method should you use?
easy
A. assertThrows()
B. assertEquals()
C. assertTrue()
D. assertNull()

Solution

  1. 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.
  2. Step 2: Compare with other assertions

    assertEquals() checks equality, assertTrue() checks boolean conditions, and assertNull() checks for null values, none of which check exceptions.
  3. Final Answer:

    assertThrows() -> Option A
  4. Quick Check:

    Exception type check = assertThrows() [OK]
Hint: Use assertThrows() to check exceptions and their subclasses [OK]
Common Mistakes:
  • Using assertEquals() to check exceptions
  • Confusing assertTrue() with exception checks
  • Expecting assertNull() to verify exceptions
2. Which of the following is the correct syntax to assert that a method throws a NullPointerException in JUnit 5?
easy
A. assertThrows(NullPointerException.class, () -> method());
B. assertThrows(NullPointerException, method());
C. assertThrows(() -> method(), NullPointerException.class);
D. assertThrows(method(), NullPointerException);

Solution

  1. Step 1: Recall assertThrows() method signature

    assertThrows() takes the exception class as the first argument and a lambda expression as the second.
  2. Step 2: Match the syntax

    assertThrows(NullPointerException.class, () -> method()); correctly uses assertThrows(NullPointerException.class, () -> method()); which matches the required syntax.
  3. Final Answer:

    assertThrows(NullPointerException.class, () -> method()); -> Option A
  4. Quick Check:

    Correct syntax = assertThrows(NullPointerException.class, () -> method()); [OK]
Hint: Exception class first, then lambda expression in assertThrows() [OK]
Common Mistakes:
  • Passing exception instance instead of class
  • Swapping argument order in assertThrows()
  • Not using lambda expression for the executable
3. Consider the following JUnit 5 test code:
assertThrows(RuntimeException.class, () -> { throw new IllegalArgumentException(); });

What will be the result of this test?
medium
A. Test fails with a compilation error
B. Test fails because IllegalArgumentException is not RuntimeException
C. Test passes because IllegalArgumentException is a subclass of RuntimeException
D. Test passes but warns about unchecked exception

Solution

  1. Step 1: Check exception hierarchy

    IllegalArgumentException extends RuntimeException, so it is a subclass.
  2. Step 2: Understand assertThrows behavior

    assertThrows(RuntimeException.class, ...) passes if the thrown exception is RuntimeException or any subclass.
  3. Final Answer:

    Test passes because IllegalArgumentException is a subclass of RuntimeException -> Option C
  4. Quick Check:

    Subclass exception passes assertThrows superclass check [OK]
Hint: assertThrows accepts subclass exceptions of the specified class [OK]
Common Mistakes:
  • Thinking exact exception type is required
  • Confusing subclass with unrelated exceptions
  • Expecting compilation error for subclass exceptions
4. Given this JUnit 5 test:
assertThrows(RuntimeException.class, () -> { throw new FileNotFoundException(); });

The test fails. What is the most likely reason?
medium
A. The lambda expression does not throw any exception
B. The test method does not declare throws IOException
C. FileNotFoundException is a checked exception and must be declared
D. FileNotFoundException is not a subclass of RuntimeException

Solution

  1. Step 1: Check exception hierarchy

    FileNotFoundException extends IOException, not RuntimeException.
  2. 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.
  3. Final Answer:

    FileNotFoundException is not a subclass of RuntimeException -> Option D
  4. Quick Check:

    Non-subclass exception causes assertThrows to fail [OK]
Hint: assertThrows requires the thrown exception to be the specified class or subclass [OK]
Common Mistakes:
  • Misidentifying exception subclass relationships
  • Ignoring checked exception declaration rules
  • Expecting runtime exceptions to behave like checked
5. You want to write a JUnit 5 test that passes if a method throws either an IOException or any of its subclasses, but fails for other exceptions. Which of the following is the best approach?
hard
A. Use assertThrows(Exception.class, () -> method()); and check instance with instanceof IOException
B. Use assertThrows(IOException.class, () -> method());
C. Use try-catch inside test and assert exception type manually
D. Use assertThrows(Throwable.class, () -> method());

Solution

  1. Step 1: Understand assertThrows behavior with superclass

    assertThrows(IOException.class, ...) passes if the thrown exception is IOException or any subclass.
  2. 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.
  3. Final Answer:

    Use assertThrows(IOException.class, () -> method()); -> Option B
  4. Quick Check:

    Superclass in assertThrows covers subclasses [OK]
Hint: Use superclass exception in assertThrows to cover subclasses [OK]
Common Mistakes:
  • Using too broad exception classes
  • Manually checking exception types unnecessarily
  • Ignoring assertThrows built-in subclass support
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard