разница между @SpringBootTest(классы = SomeController.class) и @WebMvcTest(SomeController.class)

#java #spring-boot #spring-mvc #mockito

Вопрос:

Я понимаю, что, используя @SpringbootTest я поднимаю весь весенний контекст во время теста, или, в моем случае, используя @SpringBootTest(classes = SomeController.class) я поднимаю только один компонент -> someController. Если у этого контроллера есть какие-то зависимости, мне нужно их смоделировать. Используя аннотацию @WebMvcTest(SoneController.class) , я (основываясь на своих знаниях) достигну той же цели.

Вопрос в следующем: Существуют ли какие-либо различия между этими двумя аннотациями, используемыми в приведенном примере?

Ответ №1:

Есть явная разница между @SpringBootTest(classes = SomeController.class) и @WebMvcTest(SomeController.class) .

  • @SpringBootTest(classes = SomeController.class) — запускает сервер (например, Tomcat) контекст приложения spring с компонентом SomeController.class . В дополнение к контроллеру, вы обычно должны указать конфигурацию контекста , чтобы успешно запустить все приложение (например: когда вы не указываете classes , оно возвращается к @SpringBootApplication ).
  • @WebMvcTest(SomeController.class) — запускает только веб — слой приложения SomeController.class .

В чем разница?

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

Но @WebMvcTest(SomeController.class) обычно это модульный тест для вашего контроллера. Они легкие и быстрые. Зависимости, подобные @Service классам, высмеиваются в таких тестах.

Это хорошая отправная точка — https://spring.io/guides/gs/testing-web/

Ответ №2:

Между этими двумя способами есть несколько тонких различий.
Но вы обнаружите часть из них только случайно, когда столкнетесь с такими проблемами, как исключение инициализации компонента во время инициализации контекста загрузки spring или NullPointerException повышение во время выполнения теста.
Чтобы упростить задачу, сосредоточьтесь на намерении.
Когда ты напишешь это :

 @SpringBootTest(classes = SomeController.class)
 

вы заставите Spring инициализировать только экземпляр компонента someController.
Желательно ли тестировать контроллер ?
Вероятно, нет, так как вам нужен способ вызова контроллера с помощью подхода контроллера.
Для этого мог бы помочь экземпляр MockMvc.
С помощью WebMvcTest вы получаете этот компонент, дополнительно загруженный в контекст тестирования.
Так что этот способ предпочтительнее :

 @WebMvcTest(SomeController.class)
public class SomeControllerTest{
    
  @Autowired
  private MockMvc mvc;
...
}
 

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

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

Ответ №3:

Я думаю, что для ответа на ваш вопрос достаточно просто прочитать Javadoc для обеих этих аннотаций:

1. @WebMvcTest

Аннотация, которую можно использовать для теста Spring MVC, который фокусируется только на компонентах Spring MVC.

Использование этой аннотации отключит полную автоматическую настройку и вместо этого применит только конфигурацию, относящуюся к тестам MVC (т. Е. @Controller , @ControllerAdvice @JsonComponent , Преобразователь/преобразователь, фильтр, WebMvcConfigurer и компоненты HandlerMethodArgumentResolver, но не @Component @Service или @Repository компоненты).

По умолчанию тесты с аннотациями @WebMvcTest также автоматически настраивают Spring Security и MockMvc (включая поддержку HtmlUnit WebClient и Selenium WebDriver). Для более точного управления @AutoConfigureMockMvc MockMvc можно использовать аннотацию.

@SpringBootTest

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

Использует загрузчик SpringBootContextLoader в качестве контекстного загрузчика по умолчанию, если не @ContextConfiguration(loader=...) определен конкретный. Автоматически выполняет поиск конфигурации @SpringBootConfiguration, если вложенность @Configuration не используется и явные классы не указаны. Позволяет определять пользовательские свойства среды с помощью атрибута properties.

Позволяет определять аргументы приложения с помощью атрибута args. Обеспечивает поддержку различных режимов веб-среды, включая возможность запуска полностью работающего веб-сервера, прослушивающего определенный или случайный порт. Регистрирует компонент TestRestTemplate и/или компонент WebTestClient для использования в веб-тестах, использующих полностью работающий веб-сервер.