Интеграционное тестирование в Spring: тестирование клиентских приложений

Вы можете использовать тесты на стороне клиента для тестирования кода, который внутренне использует RestTemplate. Идея состоит в том, чтобы объявить ожидаемые запросы и предоставить "заглушки" (stubs) ответов, чтобы вы могли сосредоточиться на тестировании кода изолированно (то есть без запуска сервера). В следующем примере показано, как это сделать:

RestTemplate restTemplate = new RestTemplate();

MockRestServiceServer mockServer = MockRestServiceServer
                                     .bindTo(restTemplate)
                                     .build();
mockServer.expect(requestTo("/greeting"))
          .andRespond(withSuccess());

// Тестовый код, 
// который использует вышеуказанный RestTemplate ...

mockServer.verify();

В предыдущем примере MockRestServiceServer (центральный класс для клиентских REST-тестов) настраивает RestTemplate с помощью настраиваемой ClientHttpRequestFactory, которая утверждает фактические запросы против ожиданий и возвращает "заглушки". В этом случае мы ожидаем запрос к /greeting и хотим вернуть ответ 200 с text/plain содержимым. При необходимости мы можем определить дополнительные ожидаемые запросы и ответы на заглушки. Когда мы определяем ожидаемые запросы и ответы на заглушки, RestTemplate можно использовать в коде на стороне клиента как обычно. В конце тестирования можно использовать mockServer.verify() для проверки того, что все ожидания оправдались.

По умолчанию запросы ожидаются в том порядке, в котором были объявлены ожидания. Вы можете установить опцию ignoreExpectOrder при создании сервера, и в этом случае все ожидания проверяются (по порядку), чтобы найти соответствие для данного запроса. Это означает, что запросы могут поступать в любом порядке. В следующем примере используется ignoreExpectOrder:

server = MockRestServiceServer.bindTo(restTemplate)
                              .ignoreExpectOrder(true)
                              .build();

Даже с неупорядоченными запросами по умолчанию каждый запрос может выполняться только один раз. Метод expect предоставляет перегруженный вариант, который принимает аргумент ExpectedCount, указывающий диапазон подсчета (например, once, manyTimes, max, min, between и т. д.). В следующем примере используется время:

RestTemplate restTemplate = new RestTemplate();

MockRestServiceServer mockServer = MockRestServiceServer
                                    .bindTo(restTemplate)
                                    .build();
mockServer.expect(times(2), requestTo("/something"))
          .andRespond(withSuccess());
mockServer.expect(times(3), requestTo("/somewhere"))
          .andRespond(withSuccess());

// ...

mockServer.verify();

Обратите внимание: если ignoreExpectOrder не установлен (по умолчанию) и, следовательно, запросы ожидаются в порядке объявления, то этот порядок применяется только к первому из любого ожидаемого запроса. Например, если ожидается "/something" два раза, а затем "/somewhere" три раза, то должен быть запрос к "/something" до того, как будет запрос "/somewhere", но, помимо этого последующего "/something" и "/somewhere", запросы могут приходить в любой момент.

В качестве альтернативы всему вышеперечисленному, поддержка тестирования на стороне клиента также предоставляет реализацию ClientHttpRequestFactory, которую вы можете настроить в RestTemplate, чтобы привязать его к экземпляру MockMvc. Это позволяет обрабатывать запросы, используя фактическую логику на стороне сервера, но без запуска сервера. В следующем примере показано, как это сделать:

MockMvc mockMvc = MockMvcBuilders
                   .webAppContextSetup(this.wac)
                   .build();
this.restTemplate = new RestTemplate(
           new MockMvcClientHttpRequestFactory(mockMvc));

// Тестовый код, 
// который использует вышеуказанный RestTemplate ...


Читайте также:


Комментарии

Популярные сообщения из этого блога

Методы класса Object в Java

Как получить текущий timestamp в Java

Основные опции JVM для повышения производительности и отладки