将 Spring Framework spring-test 依赖项从 4.2.9 升级到 4.3.9 后,我在运行集成测试时遇到一些问题。
我正在使用一个 ContextConfiguration 类,它实现了 spring 测试 SmartContextLoader
,它允许我加载按配置文件分割的不同 .xml 配置文件。根据当前的 spring 配置文件,它将运行该配置文件的特定 bean。
这个ContextConfigurationLoader
我在版本4.2.9
中运行得很好,但升级到版本4.3
后我正在努力解决这个问题.
我包括了我在集成测试中创建的ContextConfigurationLoader
,如下所示。
@ContextConfiguration(loader=ContextConfigurationLoader.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class MyIntegrationTest {
// Test Body
}
ContextConfigurationLoader
看起来像这样,
public class ContextConfigurationLoader implements SmartContextLoader {
@Override
public void processContextConfiguration(ContextConfigurationAttributes contextConfigurationAttributes) {
}
@Override
public ApplicationContext loadContext(MergedContextConfiguration mergedContextConfiguration) throws Exception {
GenericXmlApplicationContext context = new GenericXmlApplicationContext();
context.getEnvironment().setActiveProfiles(mergedContextConfiguration.getActiveProfiles());
new XmlBeanDefinitionReader(context).
loadBeanDefinitions(mergedContextConfiguration.getLocations());
context.load(
"/development.xml",
"/staging.xml",
"/production.xml",
);
AnnotationConfigUtils.registerAnnotationConfigProcessors(context);
context.refresh();
context.registerShutdownHook();
return context;
}
@Override
public String[] processLocations(Class<?> aClass, String... strings) {
return new String[0];
}
@Override
public ApplicationContext loadContext(String... strings) throws Exception {
ApplicationContext context = ApplicationContextFactory.create();
context.getBean("dbUnitDatabaseConnection");
return ApplicationContextFactory.create();
}
}
最后,这是我尝试运行测试后得到的错误响应。
java.lang.IllegalStateException: ContextConfigurationLoader was unable to detect defaults, and no ApplicationContextInitializers or ContextCustomizers were declared for context configuration attributes [[ContextConfigurationAttributes@53ca01a2 declaringClass = 'com.class.path.to.MyIntegrationTest', classes = '{}', locations = '{}', inheritLocations = true, initializers = '{}', inheritInitializers = true, name = [null], contextLoaderClass = 'com.class.path.to.ContextConfigurationLoader']]
感谢您的帮助,如果您需要更多信息,请告诉我。
我发现的一种解决方案是将所有 .xml 配置文件包含到一个文件中,并使用这样的 @ContextConfiguration
注释。
@ContextConfiguration("/config.xml")
但这需要对测试之外的其余代码进行一些其他更改。这也无助于解释为什么我当前的实现无法在最新的 Spring Framework spring-test 版本上工作。
最佳答案
摘自SmartContextLoader.processContextConfiguration(ContextConfigurationAttributes)的Javadoc
:
Note: in contrast to a standard ContextLoader, a SmartContextLoader must preemptively verify that a generated or detected default actually exists before setting the corresponding locations or classes property in the supplied ContextConfigurationAttributes. Consequently, leaving the locations or classes property empty signals that this SmartContextLoader was not able to generate or detect defaults.
最后一句中描述的行为是导致您出现问题的原因。
因此,解决您的问题的方法是实际实现 processContextConfiguration()
并在提供的 ContextConfigurationAttributes
中设置一个虚假位置。这将指示 Spring 您的自定义加载器能够正确检测默认值(您在 loadContext()
中硬编码)。然后,您可以从 mergedContextConfiguration.getLocations()
的副本中删除虚假位置,然后将其传递给 loadBeanDefinitions()
。
这将使最终用户变得更干净;然而,另一种选择(如果您除了自己之外没有任何最终用户)是声明现有 XML 配置文件的位置(通过 @ContextConfiguration),该文件实际上并不声明任何 bean 类。
问候,
Sam(Spring TestContext 框架的作者)
关于java - 从 Spring Framework 4.2.9 升级到 4.3+ 时自定义 ContextConfiguration Loader 出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44931127/