Java集成测试中的java.net.SocketTimeoutException,同时使用带有Spring Boot和Junit的Wiremock

时间:2019-02-27 06:10:19

标签: java spring-boot wiremock

我正在使用Wiremock模拟集成测试中的外部操作员响应:

@ClassRule
public static WireMockClassRule zainWireMockStatic = new WireMockClassRule(9900);

并获得此异常

requesting to java.net.SocketTimeoutException: connect timed out timed out

这是我的窃听器

 private static void wireMockZainUnSubscriptionRequest() {
        zainWireMockStatic.stubFor(get(urlPathMatching("/api/unsubscribe")).willReturn(
                aResponse().withStatus(200).withHeader("Content-Type", "application/json")
                        .withBody(FileUtils.readFileFromClasspath(
                                "data/mocks/zain_unsubscribe_success_response.json"))));

    }

这是我的测试

    @Test
    public void unsubscribeUserWithSuccessResponse() {
        wireMockZainUnSubscriptionRequest();
        given().body(FileUtils.readFileFromClasspath("data/message/unsubscribe_request.json"))
                .contentType(ContentType.JSON).post(UNSUBSCRIBE_API).then().statusCode(200)
                .body("user_id", equalTo(USER_ID));

    }

2 个答案:

答案 0 :(得分:1)

嗨,我遇到了同样的问题,我遵循了bernyfox on the github的建议并解决了问题。

我的问题是http客户端报告了SocketTimeout。提议的解决方案是告诉httpclient连接将以扩展名关闭。

我做了这个:

public class ConnectionCloseExtension extends ResponseTransformer {

    @Override
    public ResponseDefinition transform(Request request, ResponseDefinition response, FileSource files) {
        HttpHeaders headersWithClose;
        HttpHeader closeHeader = new HttpHeader("Connection", "Close");
        if(response.getHeaders()!=null){
            headersWithClose = HttpHeaders.copyOf(response.getHeaders())
                    .plus(closeHeader);
        }else{
            headersWithClose = new HttpHeaders(closeHeader);
        }
        response.setHeaders(headersWithClose);
        return response;
    }

    @Override
    public String name() {
        return "ConnectionCloseExtension";
    } }

并应用它:

@Rule
public WireMockRule wireMockServer = new WireMockRule(wireMockConfig()
        .extensions(new ConnectionCloseExtension()));

答案 1 :(得分:0)

问题是每个 class 一次Spring Boot运行器启动和停止其servlet容器。如果您使用WireMock规则,则每个 test方法都会启动和停止一次规则。这意味着在测试用例之间,Spring应用程序中的池化连接将变为无效。

您可以通过以下三种方法解决此问题:

  1. 切换到Spring团队的WireMock集成:http://cloud.spring.io/spring-cloud-static/spring-cloud-contract/1.1.2.RELEASE/#_spring_cloud_contract_wiremock
  2. 切换为使用@ClassRule,以便WireMock在每个测试类中启动和停止。
  3. 配置您的Spring HTTP客户端以检测和丢弃死池连接。此选项的优点是,由于许多负载平衡器/反向代理/浮动IP表现出相似的行为,因此您的应用将对生产系统中的故障转移更具弹性。