Java > Testing in Java > Unit Testing > JUnit Assertions

Asserting Exceptions with JUnit

This example demonstrates how to use JUnit to assert that a specific exception is thrown when a particular method is called.

Code Snippet

The `ExceptionThrower` class has a `riskyOperation` method that throws an `IllegalArgumentException` if the input is negative. The `ExceptionThrowerTest` class uses `assertThrows` to verify that the exception is thrown when a negative input is provided. The `assertDoesNotThrow` assertion asserts that no exception is thrown.

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertThrows;

class ExceptionThrower {
    public void riskyOperation(int input) {
        if (input < 0) {
            throw new IllegalArgumentException("Input must be non-negative");
        }
        // Some other operation
    }
}

class ExceptionThrowerTest {
    @Test
    void testRiskyOperation_throwsExceptionForNegativeInput() {
        ExceptionThrower exceptionThrower = new ExceptionThrower();
        assertThrows(IllegalArgumentException.class, () -> exceptionThrower.riskyOperation(-1), "Expected IllegalArgumentException to be thrown");
    }

    @Test
    void testRiskyOperation_noExceptionForPositiveInput() {
       ExceptionThrower exceptionThrower = new ExceptionThrower();
       org.junit.jupiter.api.Assertions.assertDoesNotThrow(() -> exceptionThrower.riskyOperation(10));
    }
}

Concepts Behind the Snippet

Exception Handling: A crucial aspect of robust software development. Properly handling exceptions prevents unexpected program termination and allows for graceful error recovery. `assertThrows()`: JUnit's assertion method specifically designed to verify that a method call throws a particular exception. It takes the expected exception class, a lambda expression representing the code that should throw the exception, and an optional message. `assertDoesNotThrow()`: JUnit's assertion method to assert that no exception occurs. It takes a lambda expression and an optional message.

Real-Life Use Case

Consider a method that parses user input. You might want to ensure that an `NumberFormatException` is thrown if the input is not a valid number. Using `assertThrows` allows you to write a unit test that specifically verifies this behavior.

Best Practices

  • Specificity: Assert for the *exact* exception type you expect. Avoid catching broader exception classes unless necessary.
  • Message Clarity: Provide clear and concise messages in your `assertThrows` call to indicate the expected behavior.
  • Isolation: Ensure that the lambda expression passed to `assertThrows` only contains the code that is *expected* to throw the exception.

When to Use Them

Use `assertThrows` whenever you want to verify that a specific method call throws an expected exception under certain conditions. This is crucial for validating error handling and ensuring the robustness of your code.

FAQ

  • What happens if the code within the lambda expression in `assertThrows` does not throw any exception?

    If no exception is thrown, the `assertThrows` assertion will fail, indicating that the code did not behave as expected.
  • Can I capture the thrown exception object using `assertThrows`?

    Yes. `assertThrows` returns the thrown exception object, allowing you to perform further assertions on its properties (e.g., message, cause).