1. Обзор
В этой статье мы рассмотрим аннотацию @WebAppConfiguration
в Spring, зачем она нам нужна в наших интеграционных тестах, а также как мы можем настроить ее, чтобы эти тесты фактически загружали WebApplicationContext
.
2. @WebAppConfiguration
Проще говоря, это аннотация уровня класса, используемая для создания веб-версии контекста приложения в Spring Framework.
Он используется для обозначения того, что ApplicationContext
, загружаемый для теста, должен быть экземпляром WebApplicationContext
.
Небольшое примечание об использовании — обычно мы находим эту аннотацию в интеграционных тестах, потому что WebApplicationContext
используется для создания объекта MockMvc
. Вы можете найти больше информации об интеграционном тестировании со Spring здесь .
3. Загрузка контекста веб -приложения
Начиная с Spring 3.2 теперь поддерживается загрузка WebApplicationContext
в интеграционных тестах :
@WebAppConfiguration
@ContextConfiguration(classes = WebConfig.class)
public class EmployeeControllerTest {
...
}
Это указывает платформе TestContext
, что для теста следует загрузить WebApplicationContext .
И в фоновом режиме создается MockServletContext
, который передается в наш тестовый WebApplicationContext
фреймворком
TestContext .
3.1. Параметры конфигурации
По умолчанию базовый путь к ресурсу для WebApplicationContext
будет установлен на «file:src/main/webapp»,
что является расположением по умолчанию для корня WAR в проекте Maven.
Однако мы можем переопределить это, просто указав альтернативный путь к аннотации @WebAppConfiguration
:
@WebAppConfiguration("src/test/webapp")
Мы также можем ссылаться на путь к базовому ресурсу из пути к классам вместо файловой системы:
@WebAppConfiguration("classpath:test-web-resources")
3.2. Кэширование
Как только WebApplicationContext
загружен, он будет кэширован и повторно использован для всех последующих тестов, которые объявляют ту же уникальную конфигурацию контекста в одном и том же наборе тестов.
Дополнительные сведения о кэшировании см. в разделе « Контекстное кэширование » справочного руководства.
4. Использование @WebAppConfiguration
в тестах
Теперь, когда мы понимаем, зачем нам нужно добавлять аннотацию @WebAppConfiguration
в наши тестовые классы, давайте посмотрим, что произойдет, если мы пропустим ее добавление при использовании WebApplicationContext
.
@RunWith(SpringJUnit4ClassRunner.class)
// @WebAppConfiguration omitted on purpose
@ContextConfiguration(classes = WebConfig.class)
public class EmployeeTest {
@Autowired
private WebApplicationContext webAppContext;
private MockMvc mockMvc;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
mockMvc = MockMvcBuilders.webAppContextSetup(webAppContext).build();
}
...
}
Обратите внимание, что мы закомментировали аннотацию, чтобы имитировать сценарий, в котором мы забыли добавить ее. Здесь легко понять, почему тест провалится, когда мы запустим тест JUnit: мы пытаемся автоматически связать WebApplicationContext
в классе, где мы его не установили .
Однако более типичным примером является тест, в котором используется веб-конфигурация Spring; этого на самом деле достаточно, чтобы сделать тестовый перерыв.
Давайте посмотрим:
@RunWith(SpringJUnit4ClassRunner.class)
// @WebAppConfiguration omitted on purpose
@ContextConfiguration(classes = WebConfig.class)
public class EmployeeTestWithoutMockMvc {
@Autowired
private EmployeeController employeeController;
...
}
Несмотря на то, что в приведенном выше примере не выполняется автоматическое подключение WebApplicationContext
, он все равно завершится ошибкой, поскольку он пытается использовать веб-конфигурацию — WebConfig
:
@Configuration
@EnableWebMvc
@ComponentScan("com.foreach.web")
public class WebConfig implements WebMvcConfigurer {
...
}
Здесь виновата аннотация @EnableWebMvc
— для этого в основном потребуется контекст Spring с поддержкой Интернета, а без него — мы увидим, что тест не пройден:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type [javax.servlet.ServletContext] found for dependency:
expected at least 1 bean which qualifies as autowire candidate for this dependency.
Dependency annotations:
{@org.springframework.beans.factory.annotation.Autowired(required=true)}
at o.s.b.f.s.DefaultListableBeanFactory
.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1373)
at o.s.b.f.s.DefaultListableBeanFactory
.doResolveDependency(DefaultListableBeanFactory.java:1119)
at o.s.b.f.s.DefaultListableBeanFactory
.resolveDependency(DefaultListableBeanFactory.java:1014)
at o.s.b.f.a.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement
.inject(AutowiredAnnotationBeanPostProcessor.java:545)
... 43 more
Вот эту проблему мы легко исправим, добавив в наши тесты аннотацию @WebAppConfiguration .
5. Вывод
В этой статье мы показали, как мы можем позволить платформе TestContext
загружать WebApplicationContext
в наши интеграционные тесты, просто добавив аннотацию.
Наконец, мы рассмотрели примеры того, что даже если мы добавим @ContextConfiguration
в тест, это не сможет работать, если мы не добавим аннотацию @WebAppConfiguration
.
Реализации примеров из этой статьи доступны в нашем репозитории на GitHub .