25

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?

dune76
  • 373
  • 1
  • 5
  • 10

5 Answers5

19

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.

Skeeve
  • 1,205
  • 3
  • 16
  • 31
  • Where is this "requestTo()" method? – Tino Oct 07 '19 at 20:21
  • 2
    @Tino org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo – AdminAffe Jan 15 '20 at 13:35
  • 1
    btw, you can just use `TimeUnit.SECONDS.sleep(1)` which is a convenience method that performs a Thread.sleep on its own. – AdminAffe Jan 15 '20 at 13:38
  • 2
    As you mentioned, this does not work if you have configured the `RestTemplate` with a third party library like OkHttp or Apache HTTP Components. – Malvon Oct 03 '20 at 02:27
  • 1
    If anyone is looking for the Kotlin version of this, replace `return new MockClientHttpResponse(myJsonResponse, HttpStatus.OK);` with `withSuccess(myJsonResponse, APPLICATION_JSON).createResponse(request)`. – Thomas Jul 23 '21 at 09:43
15

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)
);
makson
  • 1,975
  • 3
  • 23
  • 31
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);
        });
1

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("{}"))
Lewy
  • 681
  • 6
  • 7
0

In general, you can define your custom request handler, and do a nasty Thread.sleep() there.

This would be possible in Restito with something like this.

Action waitSomeTime = Action.custom(input -> {
    try {
        Thread.sleep(5000);
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }
    return input;
});

whenHttp(server).match(get("/asd"))
        .then(waitSomeTime, ok(), stringContent("Hello World"))

Not sure about Spring, however. You can easily try. Check DefaultResponseCreator for inspiration.

Sotomajor
  • 1,386
  • 11
  • 15