Throw checked Exceptions from mocks with Mockito

2.6K    Asked by artiTrivedi in Java , Asked on Jun 9, 2021

I'm trying to have one of my mocked objects throw a checked exception is invalid for this method is called

@Test(expectedExceptions = SomeException.class)
public void throwCheckedException() {
    List list = mock(List.class);
    when(list.get(0)).thenThrow(new SomeException());
    String test = list.get(0);
}
public class SomeException extends Exception {

} error.

org.testng.TestException: 
Expected exception com.testing.MockitoCheckedExceptions$SomeException but got org.mockito.exceptions.base.MockitoException: 
Checked exception is invalid for this method!
Invalid: com.testing.MockitoCheckedExceptions$SomeException

Looking at the Mockito documentation, they only use Runtime Exception, is it not possible to throw checked Exceptions from a mock object with Mockito?


Answered by Carl Paige

Check the Java API for List. The get(int) method is declared to throw only the IndexOutOfBoundException which extends RuntimeException. You are trying to tell Mockito to throw an exception that is not valid for this method to be thrown by that particular method call.

To clarify further. The List interface does not provide for a checked Exception to be thrown from the get() method and that is why Mockito is failing. When you create the mocked List, Mockito uses the definition of List.class to create its mock. The behavior you are specifying with the when(list.get(0)).thenThrow(new SomeException()) doesn't match the method signature in List.class, so Mockito fails. If you really want to do this, then have Mockito throw a new RuntimeException() or even better throw a new ArrayIndexOutOfBoundsException() since the API specifies that that is the only valid Exception to be thrown.



Your Answer

Answer (1)

In Mockito, throwing checked exceptions from mocks can be accomplished using the thenThrow method. Here's a step-by-step guide on how to achieve this:

Step-by-Step Guide

Set Up Mockito and Dependencies


    org.mockito

    mockito-core

    4.0.0

    test

Ensure you have Mockito in your project. If you are using Maven, include the following dependency in your pom.xml:

For Gradle, add the following to your build.gradle:

  testImplementation 'org.mockito:mockito-core:4.0.0' // Use the latest version

Create a Mock and Configure It to Throw an Exception

Use the when and thenThrow methods to specify that a mock should throw a checked exception.

Here’s an example of a service method that throws an IOException:

import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import java.io.IOException;
public class MyServiceTest {
    public class MyService {
        public void performAction() throws IOException {
            // Actual implementation
        }
    }

    @Test

    public void testPerformActionThrowsIOException() throws IOException {
        // Create a mock instance of MyService
        MyService myServiceMock = mock(MyService.class);
        // Configure the mock to throw IOException when performAction is called
        doThrow(new IOException("IO error")).when(myServiceMock).performAction();
        // Use the mock in your test
        try {
            myServiceMock.performAction();
        } catch (IOException e) {
            // Verify the exception
            assertEquals("IO error", e.getMessage());
        }
    }
}

Using when with Methods that Return Values

If you have a method that returns a value and you want to throw an exception, use the when syntax:

import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test;
import java.io.IOException;
public class MyServiceTest {
    public interface MyService {
        String getData() throws IOException;
    }
    @Test
    public void testGetDataThrowsIOException() throws IOException {
        // Create a mock instance of MyService
        MyService myServiceMock = mock(MyService.class);
        // Configure the mock to throw IOException when getData is called
        when(myServiceMock.getData()).thenThrow(new IOException("IO error"));
        // Use the mock in your test
        try {
            myServiceMock.getData();
        } catch (IOException e) {
            // Verify the exception
            assertEquals("IO error", e.getMessage());
        }
    }
}

Summary

  • Use doThrow for void methods to throw checked exceptions.
  • Use when(...).thenThrow for methods that return values to throw checked exceptions.
  • Ensure your test captures and asserts the expected exception.

These techniques will allow you to simulate and test the behavior of your code when checked exceptions are thrown, enabling more robust and comprehensive unit tests.


6 Months

Interviews

Parent Categories