java.lang.IllegalArgumentException: для настройки обработки сервлета по умолчанию требуется ServletContext.

У меня есть следующий тестовый класс:

@ActiveProfiles({ "DataTC", "test" })
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {BaseTestConfiguration.class, DataTestConfiguration.class, JpaConfiguration.class, PropertyPlaceholderConfiguration.class })
public class RegularDayToTimeSlotsTest {
...

Кажется, проблема связана с классом BaseTestConfiguration:

@Configuration
@ComponentScan(basePackages = { "com.bignibou" }, excludeFilters = { @Filter(type = FilterType.CUSTOM, value = RooRegexFilter.class),
        @Filter(type = FilterType.ANNOTATION, value = Controller.class), @Filter(type = FilterType.ANNOTATION, value = ControllerAdvice.class) })
public class BaseTestConfiguration {

}

Я систематически получаю это исключение:

Caused by: java.lang.IllegalArgumentException: A ServletContext is required to configure default servlet handling
    at org.springframework.util.Assert.notNull(Assert.java:112)
    at org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer.<init>(DefaultServletHandlerConfigurer.java:54)
    at org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.defaultServletHandlerMapping(WebMvcConfigurationSupport.java:329)
    at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerByCGLIB$$bb4ceb44.CGLIB$defaultServletHandlerMapping$22(<generated>)
    at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerByCGLIB$$bb4ceb44$$FastClassByCGLIB$$368bb5c1.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:326)
    at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerByCGLIB$$bb4ceb44.defaultServletHandlerMapping(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:166)
    ... 43 more

Я не уверен, как обойти эту проблему. Каким-то образом Spring ищет ServletContext, когда я запускаю тест, и я получаю указанное выше исключение...


person balteo    schedule 02.02.2014    source источник


Ответы (4)


Один из ваших классов @Configuration явно имеет аннотацию @EnableWebMvc. Вот как DelegatingWebMvcConfiguration оказывается в вашей трассировке стека, поскольку он импортируется с помощью @EnableWebMvc.

Таким образом, хотя вы думаете, что вам не нужен WebApplicationContext (и, следовательно, ServletContext), на самом деле он вам нужен просто потому, что вы загружаете контекст приложения с помощью @EnableWebMvc.

У вас есть два варианта:

  • Составьте классы конфигурации для вашего интеграционного теста, чтобы вы не включали конфигурацию, связанную с Интернетом (т. е. классы @Configuration, аннотированные @EnableWebMvc).
  • Аннотируйте свой тестовый класс с помощью @WebAppConfiguration, как было предложено в других комментариях выше.

С уважением,

Сэм (автор Spring TestContext Framework)

person Sam Brannen    schedule 03.02.2014
comment
Я попытался использовать первый вариант, который вы любезно предложили, исключив класс с аннотацией @EnableWebMvc с фильтром исключения, то есть с типом filtertype=assignable, но безрезультатно... - person balteo; 03.02.2014
comment
Также обратите внимание, что я не включаю класс @Configuration с аннотацией @EnableWebMvc в приведенный выше тест. Его подхватывает @ComponentScan в BaseTestConfiguration... - person balteo; 03.02.2014
comment
Любые советы для случая, когда это происходит при spring-boot:run (мои тесты работают нормально)? - person Aaron Zeckoski; 09.07.2014
comment
Звучит как совершенно другой вопрос для меня. Спросите новый и пометьте его spring-boot? - person Dave Syer; 11.07.2014
comment
Убедитесь, что вы загружаете контекст с помощью AnnotationConfigWebContextLoader (при использовании классов конфигурации), например: @ContextConfiguration(loader = AnnotationConfigWebContextLoader.class, classes = {ConfigClass.class}) - person Marco Ferrari; 29.09.2014
comment
Та же проблема! Но вот каким был мой случай (для справки в будущем): в TestConfig у меня был @ComponentScan(basePackages=app), а в пакете приложения был файл конфигурации, в котором был @EnableWebMvc! - person Anand Rockzz; 06.01.2015
comment
@ferrarimarco, вам не нужно объявлять AnnotationConfigWebContextLoader. Он включается по умолчанию всякий раз, когда вы объявляете атрибут classes для @ContextConfiguration. Подробнее см. в разделе Конфигурация контекста с аннотированными классами главы о тестировании в справочном руководстве Spring: docs.spring.io/spring/docs/current/spring-framework-reference/ - person Sam Brannen; 26.02.2015
comment
@ СэмБраннен, ты прав. Я форсировал AnnotationConfigContextLoader в суперклассе. Это поведение описано в документации: Если не указано, загрузчик будет унаследован от первого суперкласса, который помечен @ContextConfiguration и явно указывает загрузчик. Если ни один класс в иерархии не указывает явный загрузчик, вместо него будет использоваться загрузчик по умолчанию. - person Marco Ferrari; 01.06.2015

Кажется, тебя не хватает

@WebAppConfiguration

из вашего тестового класса.

документация состояния

Базовый путь ресурса используется для создания MockServletContext, который служит ServletContext для тестового WebApplicationContext.

Обычно контейнер сервлета предоставляет файл ServletContext. Поскольку вы находитесь в тестовой среде, вам нужна подделка. @WebAppConfiguration обеспечивает это.

person Sotirios Delimanolis    schedule 03.02.2014

Чтобы создать экземпляр контекста сервлета, вам придется использовать аннотацию.

@WebAppConfiguration

Аннотация уровня класса, которая используется для объявления того, что ApplicationContext, загруженный для интеграционного теста, должен быть WebApplicationContext. Простое присутствие @WebAppConfiguration в тестовом классе гарантирует, что WebApplicationContext будет загружен для теста с использованием значения по умолчанию «file:src/main/webapp» для пути к корню веб-приложения (т. базовый путь). Базовый путь ресурса используется для создания MockServletContext, который служит ServletContext для тестового WebApplicationContext.

person Hrishikesh    schedule 03.02.2014

Я получал аналогичную ошибку, но при обычном запуске приложения, а не при попытке запустить тесты.

Оказывается, если вы используете пользовательский PermissionEvaluator, вам нужно объявить его в отдельном классе @Configuration для того, в котором находится ваша основная конфигурация безопасности Spring.

См.: Как добавить метод на основе безопасность проекта Spring Boot?

Существует также открытая проблема Github: https://github.com/spring-projects/spring-boot/issues/4875

person Robert Hunt    schedule 12.07.2016