我正在开发自定义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测试框架本身。
有什么办法可以达到预期的效果吗?
答案 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 { /* ... */ }
然后将ApplicationContext
和FooConfig
加载BarConfig
。
以上示例显然不使用Spring Boot,但同样的原则也适用于@SpringApplicationConfiguration
。
此致
Sam( Spring TestContext Framework的作者)