防止@ComponentScan接收@ EnableWebMvc注释类

时间:2014-02-03 12:34:10

标签: spring spring-test

我有以下测试类:

@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);
    }
}

这是一个不需要任何ServletContext的集成测试。这是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),
        @Filter(type = FilterType.ANNOTATION, value = EnableWebMvc.class) })
public class BaseTestConfiguration {

}

这只是一个java配置类,旨在确保我的所有应用程序bean都被实例化并正确连接,但是没有考虑使用@EnableWebMvc注释的类,因为我不需要此集成测试的Servlet上下文。

不幸的是,无论我多少尝试排除Web / Mvc配置类,它都不起作用,并且还会选择使用@Configuration注释的@EnableWebMvc类。

我得到了这个例外:

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

有人可以帮忙吗?

2 个答案:

答案 0 :(得分:3)

事实上,有一种更简洁的方法来配置此类集成测试。

答案在于正确的关注点分离,不仅在类级别,而且在包级别。

始终建议实现和配置类都驻留在包层次结构中,以便正确分离关注点。特别是对于Web应用程序,强烈建议确保Web组件和Web配置位于专用的“Web”包中。例如,您可以考虑类似于以下的包层次结构:

  • com.example.domain
  • com.example.service
  • com.example.repository
  • com.example.web

使用这样的层次结构,您可以通过简化组件扫描配置,包括仅与当前应用程序或测试方案相关的那些基本软件包。通过这样做,通常不需要使用排除过滤器来处理您不想要的事情。相反,只需指定想要的包。

顺便说一句,指定"com.bignibou"作为你的基础包实际上是一个最差的练习,因为它是无所不包的。

因此,请使用明确的包裹内容(而不是排除@Controller@ControllerAdvice等),并查看这是否会让您的生活更轻松。 ;)

此致

萨姆

答案 1 :(得分:0)

我能够以非常污染的测试类的价格让它工作,但。这是:

@ActiveProfiles({ "DataTC", "test", "dev", "default" })
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { BaseTestConfiguration.class, DataTestConfiguration.class, JpaConfiguration.class, RestConfiguration.class, DevMailConfiguration.class,
        PropertyPlaceholderConfiguration.class, ThymeleafConfiguration.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),
        @Filter(type = FilterType.ANNOTATION, value = Configuration.class) })
@ImportResource(value="classpath*:META-INF/spring/applicationContext-security.xml")
public class BaseTestConfiguration {
...

必须有一种更简洁的方式来实施和运行集成测试......欢迎任何建议......