MockRestServiceServer имитирует время ожидания интеграции в тесте интеграции
Я пишу какой-то интеграционный тест на моем контроллере REST, используя MockRestServiceServer, чтобы издеваться над бэкэнд-поведением.
То, что я пытаюсь достичь сейчас, - это симулировать очень медленный ответ от бэкэнд, который в конечном итоге приведет к таймауту в моем приложении. Похоже, что он может быть реализован с помощью WireMock, но в данный момент я хотел бы придерживаться MockRestServiceServer.
Я создаю сервер следующим образом:
myMock = MockRestServiceServer.createServer(asyncRestTemplate);
А потом я издеваюсь над моим бэкэнд-поведением, например:
myMock.expect(requestTo("http://myfakeurl.blabla"))
.andExpect(method(HttpMethod.GET))
.andRespond(withSuccess(myJsonResponse, MediaType.APPLICATION_JSON));
Можно ли добавить какой-либо задержкой или тайм-аутом или другим типом задержки для ответа (или, может быть, всего издевавшегося сервера или даже моего asyncRestTemplate)? Или мне нужно просто переключиться на WireMock или Restito?
Ответы
Ответ 1
Вы можете реализовать эту функциональность теста следующим образом (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);
});
Но я должен предупредить вас, что, поскольку MockRestServiceServer просто заменяет RestTemplate requestFactory, любые ваши настройки requestFactory будут потеряны в тестовой среде.
Ответ 2
Подход, на который вы можете пойти:
Указание тела ответа либо ресурсом класса Path, либо нормальным содержимым строки. Более подробная версия того, что предложил Скиев выше
.andRespond(request -> {
try {
Thread.sleep(TimeUnit.SECONDS.toMillis(5)); // Delay
} catch (InterruptedException ignored) {}
return withStatus(OK).body(responseBody).contentType(MediaType.APPLICATION_JSON).createResponse(request);
});
Ответ 3
В Restito существует функция buil-in для моделирования таймаута:
import static com.xebialabs.restito.semantics.Action.delay
whenHttp(server).
match(get("/something")).
then(delay(201), stringContent("{}"))
Ответ 4
В общем, вы можете определить свой пользовательский обработчик запросов и сделать противный Thread.sleep()
там.
Это возможно в 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"))
Не уверен насчет Spring. Вы можете легко попробовать. Проверьте DefaultResponseCreator для вдохновения.
Ответ 5
Если вы контролируете тайм-аут в своем http-клиенте и используете, например, 1 секунду, вы можете использовать фиктивную задержку сервера
new MockServerClient("localhost", 1080)
.when(
request()
.withPath("/some/path")
)
.respond(
response()
.withBody("some_response_body")
.withDelay(TimeUnit.SECONDS, 10)
);
Если вы хотите сбросить соединение в Mock Server, используйте действие mock server error
new MockServerClient("localhost", 1080)
.when(
request()
.withPath("/some/path")
)
.error(
error()
.withDropConnection(true)
);