57

I have the following test class:

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

The issue seems to come from the BaseTestConfiguration class:

@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 {

}

I systematically get this exception:

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

I am not sure how to get around this issue. Somehow Spring is looking for a ServletContext when I run the test and I get the above exception...

0

4 Answers 4

142

One of your @Configuration classes is obviously annotated with @EnableWebMvc. That's how DelegatingWebMvcConfiguration ends up in your stack trace, since it is imported by @EnableWebMvc.

So although you think you don't need a WebApplicationContext (and hence a ServletContext), you in fact do need it simply because you are loading an application context with @EnableWebMvc.

You have two options:

  • Compose the configuration classes for your integration test so that you are not including the web-related configuration (i.e., the @Configuration class(es) annotated with @EnableWebMvc).
  • Annotate your test class with @WebAppConfiguration as suggested in other comments above.

Regards,

Sam (author of the Spring TestContext Framework)

Sign up to request clarification or add additional context in comments.

8 Comments

I tried to go for the first option you kindly suggested by excluding the @EnableWebMvc-annotated class with an exclude filter i.e. with an filtertype=assignable type but to no avail...
Please also note that I do not include the @Configuration class annotated with @EnableWebMvc in the above test. It is being picked up by the @ComponentScan in BaseTestConfiguration...
Any tips for the case where this is happening on spring-boot:run (my tests are running fine)?
Sounds like a completely different question to me. Ask a new one and tag it spring-boot?
Ensure that you are loading the context with an AnnotationConfigWebContextLoader (if using config classes), like this: @ContextConfiguration(loader = AnnotationConfigWebContextLoader.class, classes = {ConfigClass.class})
|
38

It seems like you are missing

@WebAppConfiguration

from your test class.

The documentation states

The resource base path is used behind the scenes to create a MockServletContext which serves as the ServletContext for the test’s WebApplicationContext.

Typically a Servlet container would provide the ServletContext. Since you are in a testing environment, you need a fake. @WebAppConfiguration provides that.

Comments

11

For you to instantiate the Servlet context, you would have to use the annotation.

@WebAppConfiguration

A class-level annotation that is used to declare that the ApplicationContext loaded for an integration test should be a WebApplicationContext. The mere presence of @WebAppConfiguration on a test class ensures that a WebApplicationContext will be loaded for the test, using the default value of "file:src/main/webapp" for the path to the root of the web application (i.e., the resource base path). The resource base path is used behind the scenes to create a MockServletContext which serves as the ServletContext for the test’s WebApplicationContext.

Comments

0

I was getting a similar error but whilst running the application normally rather than trying to run tests.

It turns out if you're making use of a custom PermissionEvaluator then you need to declare it in a separate @Configuration class to the one with your main Spring security configuration in.

See: How do I add method based security to a Spring Boot project?

There is also an open Github issue: https://github.com/spring-projects/spring-boot/issues/4875

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.