代码之家  ›  专栏  ›  技术社区  ›  jon077

如何在Java中模拟web服务器进行单元测试?

  •  34
  • jon077  · 技术社区  · 16 年前

    我想使用模拟web服务器创建一个单元测试。是否有一个用Java编写的web服务器可以从JUnit测试用例轻松启动和停止?

    9 回复  |  直到 11 年前
        1
  •  45
  •   keaplogik    5 年前

    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集成。发现的例子 here .

        2
  •  20
  •   Tilman Hausherr    4 年前

    你是想用一个 mock or an embedded 网络服务器?

    嘲弄 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 ,你可以 use in tests

        3
  •  16
  •   rogerdpack    5 年前

    您可以使用JDK的 com.sun.net.httpserver.HttpServer 类(不需要外部依赖项)。看见 this blog post 详细说明如何。

    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
    }
    
        4
  •  13
  •   Jedd Hopkins ng.    6 年前

    尝试 Simple ( Maven )它很容易嵌入到单元测试中。以RoundTripTest和以下示例为例: PostTest

    同样,Simple比Jetty轻得多,速度快得多,没有依赖性。因此,您不必在类路径中添加几个jar文件。你也不必担心 WEB-INF/web.xml

        5
  •  8
  •   Haroldo_OK    10 年前

    另一个好的选择是 MockServer ; 它提供了一个流畅的界面,您可以使用该界面定义模拟web服务器的行为。

        6
  •  7
  •   slartidan    6 年前

    你可以试试 Jadler

    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");
    
        7
  •  6
  •   rogerdpack    5 年前

    如果您使用的是ApacheHttpClient,这将是一个很好的选择。 HttpClientMock

    HttpClientMock httpClientMock = new httpClientMock() 
    HttpClientMock("http://example.com:8080"); 
    httpClientMock.onGet("/login?user=john").doReturnJSON("{permission:1}");
    

    基本上,您可以对模拟对象发出请求,然后对其进行一些验证 httpClientMock.verify().get("http://localhost/login").withParameter("user","john").called()

        8
  •  3
  •   Sled bayer    11 年前
        9
  •  1
  •   Frank Neblung    5 年前

    我推荐 Javalin . 它是模拟真实服务的极好工具,因为它允许在测试中进行状态断言(服务器端断言)。

    Wiremock

        10
  •  0
  •   rogerdpack    5 年前

    为了保证完整性,还需要使用 camel

    让您的测试类扩展 CamelTestSupport

      @Override
      protected RouteBuilder createRouteBuilder() {
        return new RouteBuilder() {
          @Override
          public void configure() {
            from("jetty:http://localhost:" + portToUse).process(
                    new Processor() {
                      @Override
                      public void process(Exchange exchange) throws Exception {
                        // Get the request information.
                        requestReceivedByServer = (String) exchange.getIn().getHeader(Exchange.HTTP_PATH);
    
                        // For testing empty response
                        exchange.getOut().setBody("your response");
                        ....
    

    获取它的示例maven依赖项:

    <dependency> <!-- used at runtime, by camel in the tests -->
      <groupId>org.apache.camel</groupId>
      <artifactId>camel-jetty</artifactId>
      <version>2.12.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.apache.camel</groupId>
      <artifactId>camel-core</artifactId>
      <version>2.12.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.apache.camel</groupId>
      <artifactId>camel-test</artifactId>
      <version>2.12.1</version>
      <scope>test</scope>
    </dependency>