Подтвердить что ты не робот

Разница между MockMvc и RestTemplate в тестах интеграции

Оба MockMvc и RestTemplate являются используется для тестов интеграции с Spring и JUnit.

Вопрос: какая разница между ними и когда мы должны выбирать один за другим?

Вот только примеры обоих вариантов:

//MockMVC example
mockMvc.perform(get("/api/users"))
            .andExpect(status().isOk())
            (...)

//RestTemplate example
ResponseEntity<User> entity = restTemplate.exchange("/api/users",
            HttpMethod.GET,
            new HttpEntity<String>(...),
            User.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
4b9b3361

Ответ 1

Как сказано в this статьи, вы должны использовать MockMvc, если хотите протестировать серверную сторону приложения:

Spring MVC Test основывается на mock-запросе и ответе от spring-test и не требует запуска контейнера сервлета. Основное отличие состоит в том, что фактическая конфигурация MVC Spring загружается через платформу TestContext и что запрос выполняется путем фактического вызова DispatcherServlet и все той же инфраструктуры Spring MVC, которая используется во время выполнения.

например:

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration("servlet-context.xml")
public class SampleTests {

  @Autowired
  private WebApplicationContext wac;

  private MockMvc mockMvc;

  @Before
  public void setup() {
    this.mockMvc = webAppContextSetup(this.wac).build();
  }

  @Test
  public void getFoo() throws Exception {
    this.mockMvc.perform(get("/foo").accept("application/json"))
        .andExpect(status().isOk())
        .andExpect(content().mimeType("application/json"))
        .andExpect(jsonPath("$.name").value("Lee"));
  }}

И RestTemplate вы должны использовать, когда хотите протестировать приложение Напоминание на стороне клиента:

Если у вас есть код, использующий RestTemplate, вы, вероятно, захотите его протестировать, и вы сможете настроить целевой сервер или высмеять RestTemplate. Поддержка тестирования REST на стороне клиента предлагает третий вариант, который заключается в использовании фактического RestTemplate, но настройте его с помощью настраиваемого ClientHttpRequestFactory, который проверяет ожидания против фактических запросов и возвращает ответы на заглушку.

Пример:

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

mockServer.expect(requestTo("/greeting"))
  .andRespond(withSuccess("Hello world", "text/plain"));

// use RestTemplate ...

mockServer.verify();

также читайте этот пример

Ответ 2

С MockMvc вы обычно настраиваете весь контекст веб-приложения и высмеиваете HTTP-запросы и ответы. Итак, хотя поддельный DispatcherServlet запущен и работает, имитируя, как будет работать ваш MVC-стек, нет реальных сетевых подключений.

С помощью RestTemplate вам необходимо развернуть фактический экземпляр сервера для прослушивания отправляемых HTTP-запросов.

Ответ 3

Можно использовать как RestTemplate, так и MockMvc!

Это полезно, если у вас есть отдельный клиент, где вы уже выполняете утомительное сопоставление объектов Java с URL-адресами и конвертируете в Json и из него, и вы хотите повторно использовать это для своих тестов MockMVC.

Вот как это сделать:

@RunWith(SpringRunner.class)
@ActiveProfiles("integration")
@WebMvcTest(ControllerUnderTest.class)
public class MyTestShould {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void verify_some_condition() throws Exception {

        MockMvcClientHttpRequestFactory requestFactory = new MockMvcClientHttpRequestFactory(mockMvc);
        RestTemplate restTemplate = new RestTemplate(requestFactory);

        ResponseEntity<SomeClass> result = restTemplate.getForEntity("/my/url", SomeClass.class);

        [...]
    }

}