基于Spring Boot的测试中的上下文层次结构



我的Spring Boot应用程序是这样启动的:

new SpringApplicationBuilder()
.sources(ParentCtxConfig.class)
.child(ChildFirstCtxConfig.class)
.sibling(ChildSecondCtxConfig.class)
.run(args);

配置类使用@SpringBootApplication进行注释。因此,我有一个根上下文和两个子网络上下文。

我想写集成测试,我希望有相同的上下文层次结构。我想至少用他的父上下文(ParentCtxConfig.class)测试第一个子上下文(用ChildFirstCtxConfig.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在子上下文中找不到/autowired。设置loader = SpringBootContextLoader.class没有帮助。

示例代码:GitHub

更新:如Peter Davis所述,此问题已在Spring Boot 1.5.0中修复。

这是@SpringBootTest的一个限制。移动准确,这是SpringBootContextLoader的限制。您可以通过使用配置父上下文的自定义上下文加载程序或使用ContextCustomizer(需要在spring.factories中列出其工厂)来解决此问题。下面是后者的一个粗略示例:

src/test/resources/META-INF/spring.factories:

org.springframework.test.context.ContextCustomizerFactory=
com.alex.demo.ctx.HierarchyContextCustomizerFactory

src/test/java.com/alex/demo/ctx/HierachyContextCustomizerFactory.java:

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,
List<ContextConfigurationAttributes> configAttributes) {
return new ContextCustomizer() {
@Override
public void customizeContext(ConfigurableApplicationContext context,
MergedContextConfiguration mergedConfig) {
if (mergedConfig.getParentApplicationContext() != null) {
context.setParent(mergedConfig.getParentApplicationContext());
}
}
};
}
}

最新更新