可以合并自定义注释中的@ContextConfiguration吗?

时间:2016-03-01 20:57:40

标签: spring-boot spring-test

我正在开发自定义Spring Boot启动器。在测试启动器中,我想要做的是实现一个组合注释,这将向@Configuration添加额外的ApplicationContext类(并且可能在TestExecutionListener中使用此注释)。例如:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@ContextConfiguration(classes = AdditionalTestConfiguration.class)
public @interface ComposedAnnotation {
}

在我的Spring Boot集成测试中使用它:

@RunWith(SpringJUnit4ClassRunner.class)
@WebIntegrationTest
@SpringApplicationConfiguration(Application.class)
@ComposedAnnotation
public class SomeTest {
}

不涉及继承。不幸的是,它似乎不起作用。我怀疑它是一个Spring Boot的东西,而不是Spring测试框架本身。

有什么办法可以达到预期的效果吗?

1 个答案:

答案 0 :(得分:1)

你是对的:这不是Spring Boot的问题。但spring-test也不是问题。

相反,它一般是Spring的预期行为。有关详细信息,请查看我对此问题的回答:@ActiveProfiles in meta annotation and on test class not working

总之,您无法通过在单个测试类上声明的两个@ContextConfiguration注释(直接或作为元注释)来实现此目的。

但是,我刚刚提出了一个技巧,它可以让你实现这个目标。具体来说,您可以创建一个ApplicationContextInitializer(ACI)来注册一个或多个@Configuration类。在组合注释中,您可以注册此ACI以注册始终存在的@Configuration。当实际使用组合注释时,它可以像正常一样声明其他@Configuration类。

我刚刚在this commit提交了一个工作示例。

基本上,代码看起来像这样:

@ContextConfiguration(loader = AnnotationConfigContextLoader.class, initializers = FooConfigInitializer.class)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ComposedContextConfiguration {

    @AliasFor(annotation = ContextConfiguration.class, attribute = "classes")
    Class<?>[] value() default {};
}
public class FooConfigInitializer implements ApplicationContextInitializer<GenericApplicationContext> {

    @Override
    public void initialize(GenericApplicationContext applicationContext) {
        new AnnotatedBeanDefinitionReader(applicationContext).register(FooConfig.class);
    }
}

你可以像这样使用它:

@RunWith(SpringRunner.class)
@ComposedContextConfiguration(BarConfig.class)
public class InitializerConfiguredViaMetaAnnotationTests { /* ... */ }

然后将ApplicationContextFooConfig加载BarConfig

以上示例显然不使用Spring Boot,但同样的原则也适用于@SpringApplicationConfiguration

此致

Sam( Spring TestContext Framework的作者