我想使用模拟Web服务器创建一个单元测试.是否有一个用Java编写的Web服务器,可以从JUnit测试用例轻松启动和停止?
Wire Mock似乎提供了一组可靠的存根和模拟来测试外部Web服务.
@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)); }
它也可以与spock集成.例如找到这里.
您是否尝试使用模拟或嵌入式 Web服务器?
对于模拟 Web服务器,尝试使用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());
对于嵌入式 Web服务器,您可以使用Jetty,您可以在测试中使用它.
尝试使用Simple(Maven)非常容易嵌入单元测试中.参加RoundTripTest和使用Simple编写的PostTest等示例.提供如何将服务器嵌入测试用例的示例.
Simple也比Jetty更轻,更快,没有依赖性.因此,您不必在类路径上添加几个jar.你也不必担心WEB-INF/web.xml
或任何其他文物.
您也可以使用JDK的com.sun.net.httpserver.HttpServer
类编写一个模拟(不需要外部依赖项).请参阅此博客文章,详细说明如何.
综上所述:
HttpServer httpServer = HttpServer.create(new InetSocketAddress(8000), 0); // or use InetSocketAddress(0) for ephemeral port 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); // or put this in an @After method or the like }
另一个好的选择是MockServer ; 它提供了一个流畅的界面,您可以使用该界面定义模拟的Web服务器的行为.
您可以尝试Jadler,它是一个具有流畅的编程Java API的库,可以在测试中存根和模拟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");
如果您使用的是apache HttpClient,这将是一个不错的选择. HttpClientMock
HttpClientMock httpClientMock = new httpClientMock()
HttpClientMock("http://example.com:8080");
httpClientMock.onGet("/login?user=john").doReturnJSON("{permission:1}");