MockRestServiceServer неправильно проверяет запрос

Я пытаюсь написать интеграционный тест для моего потока интеграции spring. Я хотел использовать MockRestServiceServer для записи и сопоставления исходящих запросов (используя http:outbound-gateway) с сервером Rest. Однако, когда я вызываю метод проверки mockServer, он не проверяется, как ожидалось.

Я пишу свои тесты следующим образом:

RestTemplate restTemplate = new RestTemplate();
MockRestServiceServer mockServer = MockRestServiceServer.createServer(restTemplate);

mockServer.expect(requestTo("adfasfadf.com")).andExpect(method(HttpMethod.GET));

// Call spring integration flow here

mockServer.verify();

Когда я проверяю метод проверки MockRestServiceServer, он не вызывает методы сопоставления RequestMatchers, и я считаю, что с этой логикой что-то не так. Я что-то упустил здесь?

/**
 * Verify that all expected requests set up via
 * {@link #expect(RequestMatcher)} were indeed performed.
 * @throws AssertionError when some expectations were not met
 */
public void verify() {
    if (this.expectedRequests.isEmpty() || this.expectedRequests.equals(this.actualRequests)) {
        return;
    }
    throw new AssertionError(getVerifyMessage());
}

person kosker    schedule 26.10.2015    source источник


Ответы (2)


После нескольких часов отладки я понял, что MockRestServiceServer запускает сопоставители во время выполнения запроса. Итак, если у вас есть обработчик исключений, связанный с выполнением запроса, ваши утверждения никогда не будут подтверждены должным образом. Этот код взят из RequestMatcherClientHttpRequest, который запускает сопоставители.

@Override
public ClientHttpResponse executeInternal() throws IOException {
    if (this.requestMatchers.isEmpty()) {
        throw new AssertionError("No request expectations to execute");
    }
    if (this.responseCreator == null) {
        throw new AssertionError("No ResponseCreator was set up. Add it after request expectations, "
                + "e.g. MockRestServiceServer.expect(requestTo(\"/foo\")).andRespond(withSuccess())");
    }
    for (RequestMatcher requestMatcher : this.requestMatchers) {
        requestMatcher.match(this);
    }
    setResponse(this.responseCreator.createResponse(this));

    return super.executeInternal();
}

Я думаю, это следует рассматривать как ошибку, так как я считаю, что утверждения должны выполняться после выполнения приложения.

person kosker    schedule 27.10.2015
comment
Привет. Есть ли билет, связанный с этим поведением? Спасибо. - person nndru; 01.06.2018

Я не использовал MockRestServiceServer раньше, но похоже, что это отличная функция. Спасибо, что указали на это!

В любом случае, согласно его исходному коду, мы имеем:

public static MockRestServiceServer createServer(RestTemplate restTemplate) {
        Assert.notNull(restTemplate, "'restTemplate' must not be null");
        MockRestServiceServer mockServer = new MockRestServiceServer();
        RequestMatcherClientHttpRequestFactory factory = mockServer.new RequestMatcherClientHttpRequestFactory();
        restTemplate.setRequestFactory(factory);
        return mockServer;
    }

Обратите внимание, пожалуйста, на RequestMatcherClientHttpRequestFactory.

Таким образом, ваш RequestMatchers может быть вызван только в том случае, если вы используете этот модифицированный RestTemplate.

Следовательно, вы должны ввести его в свой <int-http:outbound-gateway>. Или, что еще лучше, разделите экземпляр RestTemplate между этим шлюзом и этим MockRestServiceServer.

person Artem Bilan    schedule 26.10.2015
comment
Я использовал один и тот же шаблон отдыха между ‹int-http-outbound-gateway› и MockRestServiceServer. Это произошло из-за того, что сопоставители запросов выполняются во время выполнения запроса, что приводит к тому, что поток интеграции перехватывает созданную ошибку утверждения. - person kosker; 27.10.2015
comment
Есть ли решение проблемы, или я просто не могу прочитать ответ? - person PeMa; 24.10.2018