Home Arrow Icon Knowledge base Arrow Icon Global Arrow Icon What are some workarounds for throwing checked exceptions with Mockito


What are some workarounds for throwing checked exceptions with Mockito


Throwing checked exceptions with Mockito can be challenging if the method signature does not declare the exception. However, there are several workarounds to achieve this:

1. Using `willAnswer()` or `doAnswer()`**

One effective way to throw checked exceptions is by using the `willAnswer()` method from BDDMockito or the `doAnswer()` method in plain Mockito. These methods allow you to specify a custom behavior for the mock object, including throwing checked exceptions.

Here's an example using `doAnswer()`:

java
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

// Define a checked exception
public class SomeException extends Exception {
    public SomeException(String message) {
        super(message);
    }
}

// In your test class
@Test(expectedExceptions = SomeException.class)
public void throwCheckedException() {
    List list = Mockito.mock(List.class);
    
    // Use doAnswer to throw a checked exception
    Mockito.doAnswer(new Answer() {
        @Override
        public Void answer(InvocationOnMock invocation) throws Throwable {
            throw new SomeException("Custom checked exception");
        }
    }).when(list).get(0);
    
    list.get(0); // This will throw the checked exception
}

2. Throw Unchecked Exceptions**

If the method signature does not allow checked exceptions, you can throw unchecked exceptions instead. This is often recommended because Mockito works smoothly with unchecked exceptions.

For example, if you're mocking a `List` interface, you can throw an `ArrayIndexOutOfBoundsException`, which is an unchecked exception:

java
@Test(expectedExceptions = ArrayIndexOutOfBoundsException.class)
public void throwUncheckedException() {
    List list = Mockito.mock(List.class);
    when(list.get(0)).thenThrow(new ArrayIndexOutOfBoundsException());
    list.get(0); // This will throw the unchecked exception
}

3. Modify the Method Signature**

If you have control over the method you're testing, you can modify its signature to declare the checked exception. This way, Mockito will not throw an error when you use `thenThrow()` to simulate the exception.

For instance, if you have an interface like this:

java
interface SomeInterface {
    void someMethod() throws SomeException;
}

You can then mock it to throw the checked exception without issues:

java
SomeInterface mock = Mockito.mock(SomeInterface.class);
when(mock.someMethod()).thenThrow(new SomeException());

4. Use Kotlin's `given` Function**

If you're using Kotlin, you can leverage its `given` function from the `mockk` library or use Mockito's `thenAnswer` in a Kotlin context to throw checked exceptions.

Here's how you might do it with Mockito in Kotlin:

kotlin
@Test(expectedExceptions = SomeException::class)
fun throwCheckedException() {
    val list: List = mock()
    whenever(list.get(0)).thenAnswer { throw SomeException("Custom message") }
    list.get(0) // This will throw the checked exception
}

These workarounds allow you to effectively test scenarios involving checked exceptions with Mockito, even when the method signature does not explicitly declare them.

Citations:
[1] https://www.janbasktraining.com/community/java/throw-checked-exceptions-from-mocks-with-mockito
[2] https://www.w3docs.com/snippets/java/mockito-how-to-mock-and-assert-a-thrown-exception.html
[3] https://reflectoring.io/clean-unit-tests-with-mockito/
[4] https://stackoverflow.com/questions/3762047/throw-checked-exceptions-from-mocks-with-mockito
[5] https://www.youtube.com/watch?v=CCVhVSYPaMo
[6] https://rollbar.com/blog/how-to-handle-checked-unchecked-exceptions-in-java/
[7] https://blog.sammkinng.in/blogs/checked-exception-is-invalid-for-this-method
[8] https://www.tutorialspoint.com/mockito/mockito_exception_handling.htm
[9] https://www.browserstack.com/guide/mockito-throw-exception