JUnit中使用Jetty Stub服务器遇java.net.ConnectException问题求助
JUnit中使用Jetty 6.1.26 Stub服务器时出现连接拒绝异常,浏览器需等测试结束才响应
我在JUnit测试中使用org.mortbay.jetty:jetty:6.1.26搭建Stub服务器,期望返回预设内容,但执行时抛出java.net.ConnectException: Connection refused: no further information异常。另外,测试期间从浏览器访问Stub端点不会立即返回响应,要等所有JUnit执行完成、Jetty服务器关闭后才会返回预期内容,同时应用日志中出现Socket关闭异常。查了相关帖子没解决,求帮助。
详细信息
应用核心代码
应用通过CompletableFuture链式调用获取外部数据、解析并保存,实际环境运行正常:
HTTPUtilities.performGet(uri) .thenApply(HTTPUtilities::httpResponseToReader) .thenApply(reader -> parseContent(reader, id)) .thenAccept(idDetailsList -> idRepository.saveAll(idDetailsList)) .whenComplete((resp, err) -> { if (err == null) { log.info("Data for {} is successfully saved", id); } else { log.error("Exception encountered for URI {} / id : {}. Message: -> {} ", uri, id, err.getMessage()); } });
待Stub的静态方法HTTPUtilities.performGet
该方法通过线程池执行HTTP请求,实际环境正常,测试环境执行出错:
HttpUriRequest request = RequestBuilder.get() .setUri(uri) .setHeader(HttpHeaders.ACCEPT, HEADER_ACCEPT_CONSTANT) .setHeader(HttpHeaders.USER_AGENT, HEADER_USER_AGENT_CONSTANT) .build(); CompletableFuture<HttpResponse> resp = new CompletableFuture<>(); executorService.execute(() -> { try (CloseableHttpClient httpclient = HttpClients.custom().setDefaultRequestConfig(config).build(); CloseableHttpResponse response = httpclient.execute(request)) { resp.complete(response); log.info("Successfully returning response for URL: {}", uri); } catch (NullPointerException ex) { log.error("NullPointerException encountered when performing GET against URL {} with message {}", uri, ex.getCause()); resp.completeExceptionally(ex); } catch (IOException ex) { log.error("IOException encountered when performing GET against URL {} with message {}", uri, ex.getCause()); resp.completeExceptionally(ex); } }); return resp;
异常栈信息
代码执行到CloseableHttpResponse response = httpclient.execute(request)时抛出以下异常:
java.net.ConnectException: Connection refused: no further information at java.base/sun.nio.ch.Net.pollConnect(Native Method) at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:542) at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:597) at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) at java.base/java.net.Socket.connect(Socket.java:633) at org.apache.http.conn.socket.PlainConnectionSocketFactory.connectSocket(PlainConnectionSocketFactory.java:75) at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142) at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:376)
JUnit测试代码
@ExtendWith(MockitoExtension.class) public class IdRetreieveAndSaveTest { @InjectMocks UpdateIdData updateIdData; @BeforeAll static void initial() throws Exception { //Stub to replace actual call Server server = new Server(stubbedPort); Context contentOkContext = new Context(server, stubbedContext); contentOkContext.setHandler(new HttpCustomHandler()); server.setStopAtShutdown(true); server.start(); } @Test void updateIdDataTest() { List<IdData> resp = new ArrayList<>(); updateIdData.invokeHttpAndSave(id); assertEquals(100, resp.size()); } }
Jetty Handler代码
public class HttpCustomHandler extends AbstractHandler { @Override public void handle(String s, HttpServletRequest httpServletRequest, HttpServletResponse response, int i) throws IOException { OutputStream out = response.getOutputStream(); try (ByteArrayISO8859Writer writer = new ByteArrayISO8859Writer()) { writer.write(codeThatReturnsSampleDataFromExternalClient()); writer.flush(); response.setIntHeader(HttpHeaders.CONTENT_LENGTH, writer.size()); writer.writeTo(out); out.flush(); }; } }
端口监听验证
调试时执行netstat -ano | Select-String -pattern "65500",确认端口处于监听状态,测试结束后监听记录消失:
netstat -ano | Select-String -pattern "65500" TCP 0.0.0.0:65500 0.0.0.0:0 LISTENING 27448 TCP [::]:65500 [::]:0 LISTENING 27448
内容的提问来源于stack exchange,提问作者JMD
相关产品推荐
相关产品推荐

