Spring集成Wiremock测试报Software caused connection abort错误如何解决
问题根因
这个Software caused connection abort: recv failed异常本质是客户端发请求时,服务端(WireMock)已经关闭了TCP连接,结合你给出的异常现象和代码,具体原因可以定位为以下3个:
- WireMock实例生命周期管理混乱,端口冲突:你大概率给WireMock配置了固定端口,全量测试执行时,前一个测试执行完成后调用了
stop()方法关闭了WireMock实例,你的测试复用同一个端口发请求时就会连接失败。本地单独执行时没有其他测试抢占端口/销毁实例,所以运行正常;Jenkins环境的测试执行顺序和本地不同,你的测试永远排在销毁WireMock的测试之后,所以100%失败。 - HTTP连接池复用了失效连接:RestTemplate和你调用接口用的RestAssured框架默认都会开启HTTP连接池,之前测试和WireMock建立的连接被WireMock关闭后,连接池还会缓存这个无效连接,你的测试刚好是第一个复用这个无效连接的,所以只有你的测试报错。
- 代码存在明显的请求方法不匹配问题:你定义的WireMock桩是POST方法的
/my/endpoint接口,但是调用代码里用的是GET方法请求接口,即使连接正常也无法匹配到你定义的桩。
修复方案
按照优先级依次执行以下操作即可解决问题:
- 修正请求方法不匹配的问题:根据业务逻辑的实际要求,要么将桩定义改为
WireMock.get("/my/endpoint"),要么将调用代码改为post("my/endpoint")。 - 使用动态端口管理WireMock实例,统一生命周期:
不要写死WireMock端口,启动时指定动态端口:wireMockServer = new WireMockServer(WireMockConfiguration.options().dynamicPort());
启动成功后再将实际端口赋值给业务配置里的第三方服务地址,避免硬编码端口冲突。
如果多个测试类共用同一个WireMock实例,不要在每个测试的@After方法中执行stop()操作,仅在所有测试执行完成后统一关闭,每个测试执行完成后仅调用wireMockServer.resetAll()清空历史桩定义即可。 - 禁用HTTP连接池复用或者配置短存活时间:
如果使用RestAssured,增加如下配置禁止复用连接池实例:
RestAssured.config = RestAssured.config() .httpClient(HttpClientConfig.httpClientConfig() .reuseHttpClientInstance(false));
如果使用RestTemplate,将底层HttpClient的连接存活时间设置为小于单测执行时长,避免缓存无效连接。
内容的提问来源于stack exchange,提问作者Victor
相关产品推荐
相关产品推荐

