WebAppConfiguration в весенних тестах

WebAppConfiguration в весенних тестах

1. обзор

В этой статье мы рассмотрим аннотацию@WebAppConfiguration в Spring, зачем она нам нужна в наших интеграционных тестах, а также как мы можем настроить ее так, чтобы эти тесты действительно загружалиWebApplicationContext.

2. @WebAppConfigurationс

Проще говоря, это аннотация уровня класса, используемая для создания веб-версии контекста приложения в Spring Framework.

Он используется для обозначения того, чтоApplicationContext, который загружается для теста, должен быть экземпляромWebApplicationContext.

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

3. Загрузка aWebApplicationContext

Начиная с 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 он будет кэширован и повторно использован для всех последующих тестов, которые объявляют ту же уникальную конфигурацию контекста в одном и том же наборе тестов.

Дополнительные сведения о кэшировании можно найти в разделеContext caching справочного руководства.

4. Использование@WebAppConfiguration в тестах

Теперь, когда мы понимаем, почему нам нужно добавлять аннотацию@WebAppConfiguration в наши тестовые классы, давайте посмотримwhat happens if we miss adding it, когда мы используем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:we are trying to autowire the WebApplicationContext in a class where we haven’t set one.

Однако более типичным примером является тест, в котором используется конфигурация 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.example.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.