Home Arrow Icon Knowledge base Arrow Icon Global Arrow Icon Is it possible to mock API calls with varying response times using Mockito


Is it possible to mock API calls with varying response times using Mockito


Yes, it is possible to mock API calls with varying response times using Mockito. Here's how you can achieve this:

Mocking API Calls

Mockito allows you to mock objects and define their behavior when certain methods are called. For API calls, you typically use a mock object to simulate the API's response. This can be done using `RestTemplate` or any other HTTP client in your application.

Varying Response Times

To simulate varying response times, you can use Mockito's `doAnswer` method along with `Thread.sleep()` or `Awaitility` to introduce delays in the response. Here’s an example using `Thread.sleep()`:

java
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

import java.util.concurrent.TimeUnit;

public class MockApiCallTest {

    @Test
    public void testMockApiCallWithDelay() throws Exception {
        // Create a mock object
        MyService myService = Mockito.mock(MyService.class);

        // Stub the method with a delay
        Mockito.doAnswer(invocation -> {
            // Introduce a delay before returning the response
            TimeUnit.MILLISECONDS.sleep(5000); // Delay for 5 seconds
            return "Mocked Response";
        }).when(myService).makeApiCall();

        // Use the mock in your test
        String response = myService.makeApiCall();
        assert response.equals("Mocked Response");
    }
}

Using `AnswersWithDelay`

From Mockito version 2.8.44, you can use `AnswersWithDelay` to introduce delays more elegantly:

java
import org.mockito.AdditionalAnswers;
import org.mockito.Mockito;

public class MockApiCallTest {

    @Test
    public void testMockApiCallWithDelay() {
        // Create a mock object
        MyService myService = Mockito.mock(MyService.class);

        // Stub the method with a delay using AnswersWithDelay
        Mockito.doAnswer(new AdditionalAnswers.AnswersWithDelay(1000, new AdditionalAnswers.Returns("Mocked Response"))).when(myService).makeApiCall();

        // Use the mock in your test
        String response = myService.makeApiCall();
        assert response.equals("Mocked Response");
    }
}

Best Practices

- Use `@MockBean` for Spring Applications: If you're using Spring, consider using `@MockBean` to automatically inject mock objects into your application context.
- Avoid Overly Complex Mocks: If your mocks become too complex, consider creating a fake implementation instead.
- Test Isolation: Ensure that each test is isolated and doesn't interfere with others, especially when using delays.

By following these approaches, you can effectively mock API calls with varying response times using Mockito.

Citations:
[1] https://www.reddit.com/r/SpringBoot/comments/1ec2s3p/issues_with_mocking_multiple_api_calls_in_tests/
[2] https://stackoverflow.com/questions/12813881/can-i-delay-a-stubbed-method-response-with-mockito
[3] https://stackoverflow.com/questions/31512245/calling-mockito-when-multiple-times-on-same-object
[4] https://www.toptal.com/java/a-guide-to-everyday-mockito
[5] https://www.javacodegeeks.com/how-to-delay-a-stubbed-method-response-with-mockito.html
[6] https://keploy.io/blog/community/simplifying-junit-test-stubs-and-mocking
[7] https://docs.flutter.dev/cookbook/testing/unit/mocking
[8] https://www.baeldung.com/mockito-delay-stubbed-method-response
[9] https://www.youtube.com/watch?v=vcRFkp8jHJ8
[10] https://www.vogella.com/tutorials/Mockito/article.html