使用Spring Boot + WireMock时出现NoHttpResponseException

事件

我进行了商用Spring Boot应用的改修。
在该应用中,有一个部分使用了RestTemplate来调用其他相关联的系统的REST API。我使用WireMock构建了一个模拟服务器来进行包含这部分的单元测试。

根据改修进行添加了一些测试后,现有的测试突然开始抛出NoHttpResponseException: [server] failed to respond等异常并失败了。

由于在单独执行测试时能够通过,而在连续执行测试时失败,说明问题不在于测试本身而是其他原因。因此,开始调查。

原因

据说当使用HttpURLConnection作为访问WireMock的App的Http Client时会出现一个bug。

https://github.com/tomakehurst/wiremock/issues/97
Spring的RestTemplate在内部也使用了HttpURLConnection,所以涉及到这个问题。

解决办法

使用Spring Cloud Contract WireMock。

https://github.com/tomakehurst/wiremock/issues/97

由于该问题已经提供了多种解决方案,您可以选择其中之一来采用。
以下是一种初步的选择标准。

    • Spring Bootのバージョンを上げる or HttpClientを変える

 

    • 商用で動いているAppなので、テストのために構成変更は基本NG→✕

 

    • HttpClientのconnection reuseを無効化

 

    • 設定場所が分からないし、Appの動作に影響出そう→✕

 

    • spring-cloud-contract-wiremockの利用

 

    テストのライブラリ変更だけで完結→○

spring-cloud-contract-wiremock之所以取这个名字,是因为在内部使用了WireMock,因此只需最小限度更改测试代码。
具体来说,只需更改服务器配置语法,然后指定现有测试资源目录即可。
有关详细使用方法,请参考官方文档。

public class ExampleUnitTest {
    @Rule
    public WireMockRule wireMockRule = new WireMockRule(8080);
.... 
@AutoConfigureWireMock(port = 8080, stubs = "classpath*:/META-INF/**/mappings/**/*.json")
public class ExampleUnitTest {
....

如上所述,我只需将我的情况下已指定为存根(stubs)的测试资源路径处理好,现有的测试代码就可以如原样通过。

广告
将在 10 秒后关闭
bannerAds