Home Arrow Icon Knowledge base Arrow Icon Global Arrow Icon How can I use thenThrow() effectively with Mockito


How can I use thenThrow() effectively with Mockito


Using `thenThrow()` effectively with Mockito involves configuring mock objects to throw exceptions when specific methods are called. This is particularly useful for testing how your code handles exceptions from dependencies. Here's a detailed guide on how to use `thenThrow()`:

Basic Usage

The `thenThrow()` method is typically used in conjunction with `when()` to specify that a method call on a mock object should throw an exception. Here's an example:

java
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
class MyServiceTest {

    @Test
    void testThrowException() {
        // Create a mock object
        MyClass mockClass = mock(MyClass.class);
        
        // Configure the mock to throw an exception when someMethod() is called
        when(mockClass.someMethod()).thenThrow(new RuntimeException("An error occurred"));
        
        // Verify that the exception is thrown
        assertThrows(RuntimeException.class, () -> {
            mockClass.someMethod();
        });
    }
}

Handling Different Exceptions

You can configure different behaviors for a mock method by using `thenThrow()` multiple times with different exceptions. However, when stubbing more than once, the first exception will be thrown upon invoking the second stub, so ensure you test each scenario separately:

java
@Test
void testDifferentExceptions() {
    MyClass mockClass = mock(MyClass.class);
    
    // First test case: Throw one type of exception
    when(mockClass.someMethod()).thenThrow(new RuntimeException("Runtime error"));
    assertThrows(RuntimeException.class, () -> {
        mockClass.someMethod();
    });
    
    // Reset the mock for the next test case
    // mockClass = mock(MyClass.class); // If needed
    
    // Second test case: Throw another type of exception
    when(mockClass.someMethod()).thenThrow(new IllegalArgumentException("Invalid argument"));
    assertThrows(IllegalArgumentException.class, () -> {
        mockClass.someMethod();
    });
}

Void Methods

For methods that return `void`, you cannot use `when().thenThrow()` directly because there is no return value to mock. Instead, use `doThrow()`:

java
@Test
void testThrowExceptionInVoidMethod() {
    MyClass mockClass = mock(MyClass.class);
    
    // Configure the mock to throw an exception when voidMethod() is called
    doThrow(new IllegalArgumentException("Invalid argument")).when(mockClass).voidMethod();
    
    // Verify that the exception is thrown
    assertThrows(IllegalArgumentException.class, () -> {
        mockClass.voidMethod();
    });
}

Best Practices

- Use Specific Exceptions: Always use specific exception types (e.g., `IllegalArgumentException`, `IOException`) instead of general exceptions like `Exception` to ensure your tests are precise and meaningful.
- Test Exception Handling: Use `assertThrows()` to verify that the expected exception is thrown, ensuring your code handles exceptions correctly.
- Reset Mocks: If you're testing multiple scenarios with the same mock, consider resetting the mock between tests to avoid unexpected behavior.

By following these guidelines, you can effectively use `thenThrow()` with Mockito to test how your code handles exceptions from dependencies, ensuring robust error handling in your application.

Citations:
[1] https://www.javaguides.net/2023/10/mockito-thenthrow.html
[2] https://github.com/mockito/mockito/issues/282
[3] https://reflectoring.io/clean-unit-tests-with-mockito/
[4] https://dev.to/realnamehidden1_61/thenthrow-method-in-mockito-example-460l
[5] https://www.janbasktraining.com/community/java/throw-checked-exceptions-from-mocks-with-mockito
[6] https://stackoverflow.com/questions/51374553/mockito-not-throwing-exception-using-thenthrow
[7] https://www.vogella.com/tutorials/Mockito/article.html
[8] https://www.reddit.com/r/SpringBoot/comments/wrzpkp/i_need_to_write_a_test_case_where_that/
[9] https://www.toptal.com/java/a-guide-to-everyday-mockito
[10] https://www.browserstack.com/guide/mockito-throw-exception