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 {
private static int NUMBER_OF_REGULAR_DAY_TO_TIME_SLOTS_IN_WEEK = 25;
@Autowired
private AdvertisementService advertisementService;
@Test
public void shouldNotContainSaturdayNorSunday() {
Set<DayToTimeSlot> regularDayToTimeSlots = advertisementService.retrieveRegularDayToTimeSlots();
assertThat(regularDayToTimeSlots).onProperty("day").excludes(Day.SATURDAY, Day.SUNDAY);
}
@Test
public void shouldNotContainEveningNorNighttime() {
Set<DayToTimeSlot> regularDayToTimeSlots = advertisementService.retrieveRegularDayToTimeSlots();
assertThat(regularDayToTimeSlots).onProperty("timeSlot").excludes(TimeSlot.EVENING, TimeSlot.NIGHTTIME);
}
@Test
public void shouldContainCorrectNumberOfDayToTimeSlots() {
Set<DayToTimeSlot> regularDayToTimeSlots = advertisementService.retrieveRegularDayToTimeSlots();
assertThat(regularDayToTimeSlots).hasSize(NUMBER_OF_REGULAR_DAY_TO_TIME_SLOTS_IN_WEEK);
}
}
This is an integration test that does not need any ServletContext. Here is 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),
@Filter(type = FilterType.ANNOTATION, value = EnableWebMvc.class) })
public class BaseTestConfiguration {
}
This is just a java configuration class that is meant to ensure that all of my application beans are instantiated and wired up correctly but that the class annotated with @EnableWebMvc is not taken into account because I don't need a Servlet context for this integration test.
Unfortunately, however much I try to exclude the Web/Mvc configuration class, it does not work and the @Configuration class annotated with @EnableWebMvc is also picked up.
I 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$$d1263fa1.CGLIB$defaultServletHandlerMapping$22(<generated>)
at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerByCGLIB$$d1263fa1$$FastClassByCGLIB$$e0423f09.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$$d1263fa1.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
Can anyone please help?
There is in fact a cleaner way to configure such integration tests.
The answer lies in proper separation of concerns, not only at the class level but also at the package level.
It is always recommended that both implementation and configuration classes reside in package hierarchies that allow for proper separation of concerns. Specifically for a web application, it is highly advisable to ensure that web components and web configuration reside in a dedicated 'web' package. For example, you could consider a package hierarchy similar to the following:
com.example.domaincom.example.servicecom.example.repositorycom.example.webWith such a hierarchy you can simplify your component scanning configuration by including only those base packages that are pertinent to the current application or test scenario. By doing this there is typically no need to use exclusion filters for things you don't want. Instead, just specify packages you do want.
By the way, specifying "com.bignibou" as your base package is actually a worst practice since it is all-encompassing.
So give it a shot with explicit package inclusions (instead of excluding @Controller, @ControllerAdvice, etc.) and see if that doesn't make your life easier. ;)
Regards,
Sam
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With