java - 从 Spring Framework 4.2.9 升级到 4.3+ 时自定义 ContextConfiguration Loader 出现问题

标签 java spring spring-test context-configuration spring-framework-beans

将 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/

相关文章:

java - 谷歌地图不会显示

spring - tomcat + spring +quartz = 关闭错误

java - Spring MVC 教程项目不基于 IntelliJ 构建

java - 当 session 超时导致多部分表单 POST 中断时出现异常

java - JUnit:为测试类设置事务边界

Spring Batch - 如何使用 jobLauncherTestUtils 防止数据库提交

spring-boot - 将@SpyBean 与@Qualifier Spring Boot 测试一起使用

java - 使用 Java 的 HttpUrlConnection PATCH 请求

java - 具有不可变值的 ConcurrentHashMap - 同步替换?

java - 从 JTextPane 获取 JLabel 并更改其文本