第一次测试后,junit中的HttpServer因地址使用错误而失败

jmk*_*een 3 java junit com.sun.net.httpserver

我有一个Java类用于JUnit 4.x. 在每个@Test方法中,我创建了一个新的HttpServer,使用了端口9090.第一个调用工作查找,但后续的错误与"地址已被使用:绑定".

这是一个例子:

@Test
public void testSendNoDataHasValidResponse() throws Exception {
    InetSocketAddress address = new InetSocketAddress(9090);
    HttpHandler handler = new HttpHandler() {

        @Override
        public void handle(HttpExchange exchange) throws IOException {
            byte[] response = "Hello, world".getBytes();
            exchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, response.length);
            exchange.getResponseBody().write(response);
            exchange.close();
        }
    };
    HttpServer server = HttpServer.create(address, 1);
    server.createContext("/me.html", handler);
    server.start();

    Client client = new Client.Builder(new URL("http://localhost:9090/me.html"), 20, "mykey").build();

    client.sync();
    server.stop(1);
    assertEquals(true, client.isSuccessfullySynchronized());
}
Run Code Online (Sandbox Code Playgroud)

很明显,HttpServer仅在每个方法中保存,并在结束前停止.我没有看到什么继续保持任何套接字打开.第一次测试通过,后续测试每次都失败.

有任何想法吗?

使用更正方法编辑:

@Test
public void testSendNoDataHasValidResponse() throws Exception {
    server = HttpServer.create(new InetSocketAddress("127.0.0.1", 0), 1);
    HttpHandler handler = new HttpHandler() {

        @Override
        public void handle(HttpExchange exchange) throws IOException {
            byte[] response = "Hello, world".getBytes();
            exchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, response.length);
            exchange.getResponseBody().write(response);
            exchange.close();
        }
    };
    server.createContext("/me.html", handler);
    server.start();
    InetSocketAddress address = server.getAddress();
    String target = String.format("http://%s:%s/me.html", address.getHostName(), address.getPort());

    Client client = new Client.Builder(new URL(target), 20, "mykey").build();

    client.sync();
    server.stop(0);
    assertEquals(true, client.isSuccessfullySynchronized());
}
Run Code Online (Sandbox Code Playgroud)

Tom*_*son 5

jello的回答是钱.

其他解决方法:

  • 为所有测试重用相同的HttpServer.要在测试之间清理它,您可以删除它的所有上下文.如果您给它一个自定义执行程序,您也可以等待或终止所有工作线程.

  • 在新端口上创建每个HttpServer.您可以通过在创建InetSocketAddress时指定端口号为零来执行此操作.然后,您可以在创建服务器查询服务器的端口,找到正在使用的实际端口,并在测试中使用它.

  • 将全局服务器套接字工厂更改为自定义工厂,每次返回相同的服务器套接字.这使得您可以为许多测试重用相同的实际套接字,而无需重用HttpServer.