MockRestServiceServer simulate backend timeout in integration test

17,181

Solution 1

You can implement this test functionality this way (Java 8):

myMock
    .expect(requestTo("http://myfakeurl.blabla"))
    .andExpect(method(HttpMethod.GET))
    .andRespond(request -> {
        try {
            Thread.sleep(TimeUnit.SECONDS.toMillis(1));
        } catch (InterruptedException ignored) {}
        return new MockClientHttpResponse(myJsonResponse, HttpStatus.OK);
    });

But, I should warn you, that since MockRestServiceServer simply replaces RestTemplate requestFactory any requestFactory settings you'd make will be lost in test environment.

Solution 2

If you control timeout in your http client and use for example 1 seconds you can use mock server delay

new MockServerClient("localhost", 1080)
.when(
    request()
        .withPath("/some/path")
)
.respond(
    response()
        .withBody("some_response_body")
        .withDelay(TimeUnit.SECONDS, 10)
);

If you want to drop connection in Mock Server use mock server error action

new MockServerClient("localhost", 1080)
.when(
    request()
        .withPath("/some/path")
)
.error(
    error()
        .withDropConnection(true)
);

Solution 3

Approach that you can go for: Specifying the responsebody either with Class Path resource or normal string content. More detailed version of what Skeeve suggested above

.andRespond(request -> {
            try {
                Thread.sleep(TimeUnit.SECONDS.toMillis(5)); // Delay
            } catch (InterruptedException ignored) {}
            return withStatus(OK).body(responseBody).contentType(MediaType.APPLICATION_JSON).createResponse(request);
        });

Solution 4

In Restito, there is a buil-in function to simulate timeout:

import static com.xebialabs.restito.semantics.Action.delay

whenHttp(server).
   match(get("/something")).
   then(delay(201), stringContent("{}"))
Share:
17,181
dune76
Author by

dune76

Updated on June 06, 2022

Comments

  • dune76
    dune76 almost 2 years

    I am writing some kind of integration test on my REST controller using MockRestServiceServer to mock backend behaviour. What I am trying to achieve now is to simulate very slow response from backend which would finally lead to timeout in my application. It seems that it can be implemented with WireMock but at the moment I would like to stick to MockRestServiceServer.

    I am creating server like this:

    myMock = MockRestServiceServer.createServer(asyncRestTemplate);
    

    And then I'm mocking my backend behaviour like:

    myMock.expect(requestTo("http://myfakeurl.blabla"))
                .andExpect(method(HttpMethod.GET))
                .andRespond(withSuccess(myJsonResponse, MediaType.APPLICATION_JSON));
    

    Is it possible to add some kind of a delay or timeout or other kind of latency to the response (or maybe whole mocked server or even my asyncRestTemplate)? Or should I just switch to WireMock or maybe Restito?