我的Spring Boot应用程序启动如下:
new SpringApplicationBuilder() .sources(ParentCtxConfig.class) .child(ChildFirstCtxConfig.class) .sibling(ChildSecondCtxConfig.class) .run(args);
配置类使用注释@SpringBootApplication
.因此,我有一个根上下文和两个子Web上下文.
我想编写集成测试,我希望在那里有相同的上下文层次结构.我希望至少ChildFirstCtxConfig.class
用他的父上下文(ParentCtxConfig.class
)测试第一个子上下文(配置).我怎样才能做到这一点?
目前我ApplicationContext
在我的测试中自动装配,所以我可以检查它.我在测试中有这个类注释:
@RunWith(SpringRunner.class) @SpringBootTest(classes = { ParentCtxConfig.class, ChildFirstCtxConfig.class }, webEnvironment = WebEnvironment.RANDOM_PORT)
但这将产生单个上下文,我想要父子层次结构.我假设我应该用@ContextHierarchy
注释来注释我的测试.
将我的测试注释更改为这似乎与前面的示例完全相同:
@RunWith(SpringRunner.class) @ContextConfiguration(classes = { ParentCtxConfig.class, ChildFirstCtxConfig.class }) @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
但是,如果我想介绍@ContextHierarchy
并有这样的事情:
@RunWith(SpringRunner.class) @ContextHierarchy({ @ContextConfiguration(name = "root", classes = ParentCtxConfig.class), @ContextConfiguration(name = "child", classes = ChildFirstCtxConfig.class) }) @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
由于在父上下文中定义的bean无法在子上下文中找到/自动装配,因此未启动上下文.设置loader = SpringBootContextLoader.class
没有帮助.
示例代码:GitHub
更新: 如Peter Davis所述,Spring Boot 1.5.0修复了此问题.
这是一个限制@SpringBootTest
.准确地移动,这是一个限制SpringBootContextLoader
.您可以使用自定义上下文加载器来配置父上下文或ContextCustomizer
需要列出的工厂spring.factories
.以下是后者的一个粗略示例:
org.springframework.test.context.ContextCustomizerFactory=\ com.alex.demo.ctx.HierarchyContextCustomizerFactory
package com.alex.demo.ctx; import java.util.List; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.test.context.ContextConfigurationAttributes; import org.springframework.test.context.ContextCustomizer; import org.springframework.test.context.ContextCustomizerFactory; import org.springframework.test.context.MergedContextConfiguration; public class HierarchyContextCustomizerFactory implements ContextCustomizerFactory { @Override public ContextCustomizer createContextCustomizer(Class> testClass, ListconfigAttributes) { return new ContextCustomizer() { @Override public void customizeContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig) { if (mergedConfig.getParentApplicationContext() != null) { context.setParent(mergedConfig.getParentApplicationContext()); } } }; } }