我有一个用于 JUnit 4.x 的 Java 类。在每个 @Test 方法中,我创建一个新的 HttpServer,使用端口 9090。第一次调用可以找到,但随后的调用会出现“地址已在使用中:绑定(bind)”的错误。
这是一个例子:
@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());
}
很明显,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());
}
最佳答案
果冻的答案是钱。
其他解决方法:
为所有测试重复使用相同的 HttpServer。要在测试之间清理它,您可以删除它的所有上下文。如果你给它一个自定义执行器,你也可以等待或杀死所有工作线程。
在新端口上创建每个 HttpServer。你可以通过specifying a port number of zero when creating the InetSocketAddress来做到这一点.然后您可以通过 querying the server for its port 找到实际使用的端口创建它之后,并在测试中使用它。
Change the global server socket factory到一个自定义工厂,它每次都返回相同的服务器套接字。这让您可以为许多测试重用相同的实际套接字,而不必重用 HttpServer。
关于java - 第一次测试后,junit 中的 HttpServer 因地址使用错误而失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10607633/