Разница между использованием MockMvc с SpringBootTest и использованием WebMvcTest

Я новичок в Spring Boot и пытаюсь понять, как работает тестирование SpringBoot. Я немного смущен о том, какая разница между следующими двумя фрагментами кода:

Фрагмент кода 1:

@RunWith(SpringRunner.class)
@WebMvcTest(HelloController.class)
public class HelloControllerApplicationTest {
    @Autowired    
    private MockMvc mvc;

    @Test
    public void getHello() throws Exception {
        mvc.perform(MockMvcRequestBuilders.get("/").accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andExpect(content().string(equalTo("Greetings from Spring Boot!")));
    }
}

В этом тесте используется аннотация @WebMvcTest, которая, как я полагаю, предназначена для тестирования фрагментов компонентов и проверяет только уровень Mvc веб-приложения.

Фрагмент кода 2:

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class HelloControllerTest {

    @Autowired
    private MockMvc mvc;

    @Test
    public void getHello() throws Exception {
    mvc.perform(MockMvcRequestBuilders.get("/").accept(MediaType.APPLICATION_JSON))
            .andExpect(status().isOk())
            .andExpect(content().string(equalTo("Greetings from Spring Boot!")));
    }
}

В этом тесте используется аннотация @SpringBootTest и MockMvc. Итак, как это отличается от фрагмента кода 1? Что это делает по-другому?

Изменить: Добавление фрагмента кода 3 (найдено это как пример тестирования интеграции в документации Spring)

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class HelloControllerIT {

@LocalServerPort
private int port;

private URL base;

@Autowired
private TestRestTemplate template;

@Before
public void setUp() throws Exception {
    this.base = new URL("http://localhost:" + port + "/");
}

@Test
public void getHello() throws Exception {
    ResponseEntity<String> response = template.getForEntity(base.toString(),
            String.class);
    assertThat(response.getBody(), equalTo("Greetings from Spring Boot!"));
}
}

Ответы

Ответ 1

@SpringBootTest - это общая аннотация теста. Если вы ищете что-то, что делает то же самое до 1.4, то что вы должны использовать. Он вообще не использует нарезку, что означает, что он запустит весь контекст приложения и не настроит сканирование компонентов вообще.

@WebMvcTest будет сканировать только определенный вами контроллер и инфраструктуру MVC. Это. Так что, если ваш контроллер имеет некоторую зависимость от других bean-компонентов от сервисного уровня, тест не запустится, пока вы сами не загрузите эту конфигурацию или не предоставите ее для проверки. Это намного быстрее, так как мы загружаем только небольшую часть вашего приложения. Эта аннотация использует нарезку.

Чтение документа, вероятно, также поможет вам.

Ответ 2

Аннотация @SpringBootTest указывает Spring Boot пойти и поискать основной класс конфигурации (например, класс с @SpringBootApplication) и использовать его для запуска контекста приложения Spring. SpringBootTest загружает завершенное приложение и внедряет все компоненты, которые могут быть медленными.

@WebMvcTest - для тестирования уровня контроллера, и вам необходимо предоставить оставшиеся зависимости, необходимые для использования Mock Objects.

Еще несколько аннотаций ниже для вашей справки.

Тестирование фрагментов приложения Иногда вы хотите протестировать простой "фрагмент" приложения вместо автоматической настройки всего приложения. Spring Boot 1.4 представляет 4 новые аннотации теста:

@WebMvcTest - for testing the controller layer
@JsonTest - for testing the JSON marshalling and unmarshalling
@DataJpaTest - for testing the repository layer
@RestClientTests - for testing REST clients

Обратитесь за дополнительной информацией: https://spring.io/guides/gs/testing-web/

Ответ 3

Тесты MVC предназначены для охвата только части контроллера вашего приложения. HTTP-запросы и ответы проверяются, поэтому реальные соединения не создаются. С другой стороны, когда вы используете @SpringBootTest, загружается вся конфигурация для контекста веб-приложения, и соединения проходят через настоящий веб-сервер. В этом случае вы используете не компонент MockMvc, а стандартный взамен RestTemplate (или новый альтернативный TestRestTemplate).

Итак, когда мы должны выбрать один или другой? @WebMvcTest предназначен для однократного тестирования контроллера со стороны сервера. @SpringBootTest, с другой стороны, следует использовать для интеграционных тестов, когда вы хотите взаимодействовать с приложением со стороны клиента.

Это не означает, что вы не можете использовать макеты с @SpringBootTest; если вы пишете интеграционный тест, это все еще может быть необходимо. В любом случае, лучше не использовать его только для простого тестирования модулей контроллеров.

source - Изучение микросервисов с помощью Spring Boot