Я хотел бы создать единичный тест, используя макет веб-сервера. Есть ли веб-сервер, написанный на Java, который можно легко запустить и остановить из тестового примера JUnit?Как издеваться над веб-сервером для модульного тестирования на Java?
ответ
Попробуйте Simple (Maven) его очень легко внедрить в единичный тест. Возьмите RoundTripTest и примеры, такие как PostTest, написанный с помощью Simple. Предоставляет пример внедрения сервера в тестовый пример.
Также простой намного легче и быстрее, чем Jetty, без зависимостей. Таким образом, вам не придется добавлять несколько банок в свой класс. Вы также не должны беспокоиться о WEB-INF/web.xml
или других артефактах.
Несмотря на то, что, возможно, это именно то, чего хочет пользователь, это не «макет» веб-сервера, который является фактическим веб-сервером, который запускается в рамках модульного теста.Например, если порт был взят, он потерпит неудачу, поэтому не настоящий макет (т. Е. Имеет внешнюю зависимость от системы). Согласно номенклатуре Мартина Фаулера [«Test Doubles»] (http://www.martinfowler.com/bliki/TestDouble.html), это «подделка». Тем не менее, это было именно то, что я искал. – ArtB
Неужели этот проект не прошел? – kbolino
Попробуйте использовать Jetty web server.
Вы пытаетесь использовать веб-сервер mock or an embedded?
Для веб-сервера издеваться, попробуйте использовать Mockito, или что-то подобное, и просто издеваются над HttpServletRequest
и HttpServletResponse
объекты, такие как:
MyServlet servlet = new MyServlet();
HttpServletRequest mockRequest = mock(HttpServletRequest.class);
HttpServletResponse mockResponse = mock(HttpServletResponse.class);
StringWriter out = new StringWriter();
PrintWriter printOut = new PrintWriter(out);
when(mockResponse.getWriter()).thenReturn(printOut);
servlet.doGet(mockRequest, mockResponse);
verify(mockResponse).setStatus(200);
assertEquals("my content", out.toString());
Для веб-сервера встроенный, вы могли бы использовать Jetty, который вы можете use in tests.
Посмотрите https://github.com/oharsta/priproba
Другой хорошей альтернативой будет MockServer; он обеспечивает свободный интерфейс, с помощью которого вы можете определить поведение издевающегося веб-сервера.
Также MockServer зависит от Netty (не Jetty). –
Wire Mock, похоже, предлагает надежный набор заглушек и макетов для тестирования внешних веб-сервисов.
@Rule
public WireMockRule wireMockRule = new WireMockRule(8089);
@Test
public void exactUrlOnly() {
stubFor(get(urlEqualTo("/some/thing"))
.willReturn(aResponse()
.withHeader("Content-Type", "text/plain")
.withBody("Hello world!")));
assertThat(testClient.get("/some/thing").statusCode(), is(200));
assertThat(testClient.get("/some/thing/else").statusCode(), is(404));
}
Он может быть интегрирован с помощью спока. Пример найден here.
Это работало очень хорошо для меня. Использование wireMockConfig(). DynamicPort() делает его более предсказуемым в настройке, где другие программы могут использовать порт. Мне жаль, что это не было по умолчанию, поскольку я почти пропустил эту возможность и пропустил эту великую библиотеку. – morten
Что такое testClient в коде, который вы указали? – gribo
@gribo Предполагаю, что testClient - ваш фактический экземпляр под тестированием. – Stephan
Вы можете попробовать Jadler (http://jadler.net), который представляет собой библиотеку с плавным программным API Java для заглушки и издевки ресурсов http в ваших тестах. Пример:
onRequest()
.havingMethodEqualTo("GET")
.havingPathEqualTo("/accounts/1")
.havingBody(isEmptyOrNullString())
.havingHeaderEqualTo("Accept", "application/json")
.respond()
.withDelay(2, SECONDS)
.withStatus(200)
.withBody("{\\"account\\":{\\"id\\" : 1}}")
.withEncoding(Charset.forName("UTF-8"))
.withContentType("application/json; charset=UTF-8");
Я пробовал использовать Jadler, но всякий раз, когда я пытаюсь вызвать 'initJadler()', я получаю сообщение об ошибке https://github.com/jadler-mocking/jadler/issues/107. Любые мысли, что может быть неправильным? – tuk
Не могли бы вы вставить результат зависимости mvn: tree здесь? Это может быть столкновение библиотек. –
Пожалуйста, прочтите мой ответ в github.com/jadler-mocking/jadler/issues/107, проблема вызвана столкновением версий Jetty (8 против 9). Вы можете либо удалить зависимость Jetty9 (если это не требуется для тестового запуска), либо запустить Jadler без зависимости Jetty (https://github.com/jadler-mocking/jadler/wiki/Using-the-Alternative-Stub-Server -Implementation) –
Вы можете написать макет с HttpServer
классе JDK, как хорошо (не требуется никаких внешних зависимостей). См. this blog post подробно о том, как.
В итоге:
HttpServer httpServer = HttpServer.create(new InetSocketAddress(8000), 0);
httpServer.createContext("/api/endpoint", new HttpHandler() {
public void handle(HttpExchange exchange) throws IOException {
byte[] response = "{\"success\": true}".getBytes();
exchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, response.length);
exchange.getResponseBody().write(response);
exchange.close();
}
});
httpServer.start();
try {
// Do your work...
} finally {
httpServer.stop(0);
}
Есть ли способ утверждать, получил ли запрос 'HttpServer' запрос? –
Если вы используете апачский HttpClient, это будет хорошей альтернативой. HttpClientMock
HttpClientMock httpClientMock = new httpClientMock()
HttpClientMock("http://example.com:8080");
httpClientMock.onGet("/login?user=john").doReturnJSON("{permission:1}");
ПОЛНОЕ ОПИСАНИЕ: Я являюсь автором библиотеки.
Задача больше похожа на создание интеграционного теста, а не на единичный тест. –