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