java MockRestServiceServer 在集成测试中模拟后端超时

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37076113/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 02:10:25  来源:igfitidea点击:

MockRestServiceServer simulate backend timeout in integration test

javaspringmockingmockitomockmvc

提问by dune76

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.

我正在使用 MockRestServiceServer 在我的 REST 控制器上编写某种集成测试来模拟后端行为。我现在想要实现的是模拟来自后端的非常缓慢的响应,这最终会导致我的应用程序超时。似乎可以用 WireMock 实现,但目前我想坚持使用 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?

是否可以为响应添加某种延迟或超时或其他类型的延迟(或者可能是整个模拟服务器甚至我的 asyncRestTemplate)?或者我应该切换到 WireMock 或者 Restito?

回答by Skeeve

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

您可以通过这种方式实现此测试功能(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.

但是,我应该警告您,由于 MockRestServiceServer 只是替换了 RestTemplate requestFactory,您所做的任何 requestFactory 设置都将在测试环境中丢失。

回答by Pratik Kotadia

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

您可以采用的方法:使用类路径资源或普通字符串内容指定响应主体。Skeeve 上面建议的更详细的版本

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

回答by Lewy

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

Restito 中,有一个内置函数来模拟超时:

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

whenHttp(server).
   match(get("/something")).
   then(delay(201), stringContent("{}"))

回答by makson

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

如果您在 http 客户端控制超时并使用例如 1 秒,您可以使用模拟服务器延迟

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

如果您想在 Mock Server 中断开连接,请使用mock server error action

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

回答by Sotomajor

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

一般来说,您可以定义您的自定义请求处理程序,并在Thread.sleep()那里做一些讨厌的事情。

This would be possible in Restitowith something like this.

这在Restito 中可以通过这样的方式实现。

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 DefaultResponseCreatorfor inspiration.

然而,不确定春天。您可以轻松尝试。检查DefaultResponseCreator以获得灵感。