自定义注解中的@ContextConfiguration是否可以合并?

Can @ContextConfiguration in a custom annotation be merged?

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

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

并在我的 Spring 引导集成测试中使用它:

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

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

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

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

的问题

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

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

不过,我想出了一个 技巧 可以让您实现这一目标。具体来说,您可以创建一个 ApplicationContextInitializer (ACI) 来注册一个或多个 @Configuration classes。然后,在您的组合注释中,您可以注册此 ACI 以注册 always present @Configuration classes。并且在实际使用组合注解时,它可以声明额外的 @Configuration class 像正常一样。

我刚刚在 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 { /* ... */ }

然后将从 FooConfigBarConfig.

加载您的 ApplicationContext

上面的例子显然没有使用Spring引导,但同样的原理应该也适用于@SpringApplicationConfiguration.

此致,

Sam(Spring TestContext Framework 的作者)