Java.net.SocketTimeoutException в тесте интеграции в Java при использовании Wiremock с использованием Spring Boot с Junit

Я использую 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));

    }
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
3 063
2

Ответы 2

Проблема в том, что бегун Spring Boot запускает и останавливает свой контейнер сервлета один раз для класс. Если вы используете правило WireMock, оно запускается и останавливается один раз для Метод испытания. Это означает, что объединенные в пул соединения в приложении Spring становятся недействительными между тестовыми примерами.

У вас есть три варианта исправить это:

  1. Переключиться на интеграцию WireMock команды Spring: http://cloud.spring.io/spring-cloud-static/spring-cloud-contract/1.1.2.RELEASE/#_spring_cloud_contract_wiremock
  2. Переключитесь на использование @ClassRule, чтобы WireMock запускался и останавливался для каждого тестового класса.
  3. Настройте HTTP-клиент Spring на обнаружение и отбрасывание мертвых соединений из пула. Преимущество этого варианта заключается в том, что ваше приложение будет более устойчивым к отказам в производственной системе, поскольку многие балансировщики нагрузки/обратные прокси/плавающие IP-адреса будут демонстрировать аналогичное поведение.

Привет, у меня была такая же проблема, и я последовал совету Бернифокс на гитхабе и решил проблему.

Моя проблема была с 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()));

Другие вопросы по теме