弹簧 - 在加载测试或主要配置之间切换

时间:2013-03-21 11:19:36

标签: java spring

我正在尝试交换应用程序上下文文件,这样我就可以在我的IDE中使用真实的测试或在我的IDE中使用带有测试的JUnit进行测试。

一个简单的例子是:

mainConfig.xml

<context:component-scan base-package="myPackage" />
<bean id="myBean" class="my.class"/>

testConfig.xml

<context:component-scan base-package="myPackage" />
<bean id="myBean" class="my.test.class"/>

我处理应用程序Context的java代码与下面类似(但实际上是单例)

public final class MyLoader {

    private ApplicationContext context;

    public MyLoader(){
        context = new ClassPathXmlApplicationContext(
            "classpath:/hardcoded/path/to/mainConfig.xml");
    }

    public <T> T getComponent(final Class<T> type) {
        return (T) context.getBean(type);
    }
}

MyLoader是从代码中的多个点调用的,因为应用程序有许多不同的入口点。

我的JUnit测试代码

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:/hardcoded/path/to/testConfig.xml")
public final class Foo{}

当我运行JUnit测试时,它将加载testConfig.xml(由于JUnit文件中的@ContextConfiguration),但它也将加载mainConfig.xml(因为ClassPathXmlApplication)。这会导致冲突,因为这两个文件不同。

如果不发生这样的不匹配,将所有这些连线的正确方法是什么?

2 个答案:

答案 0 :(得分:1)

考虑到加载spring上下文和访问bean的方式,你似乎有一个特定的场景。

针对您的具体问题的解决方案:

  • 类路径优先。 将main.xmltest.xml个文件放在不同的目录中,但两者使用相同的名称(例如main/config.xmltest/config.xml)。然后配置IDE,以便在运行jUnit时,测试目录优先于类路径中的主目录。

    这实际上是maven默认获得的内容。在这种情况下,您可能需要通过使用IDE来自己烹饪。

  • 环境变量。 另一个选项是用于配置config.xml位置的环境变量,然后在MyLoader中使用该值,可能默认为main.xml以避免在正常执行中进行额外配置。

    public MyLoader(){
      context = new ClassPathXmlApplicationContext(
          System.getProperty("config.location", "classpath:path/to/mainConfig.xml"));
    

    然后,您可以配置IDE以在运行jUnit时设置该环境变量,或者从相应地设置变量的基类扩展测试:

    System.setProperty("config.location", "classpath:/path/to/testConfig.xml")
    

    这里你真的不需要SpringJUnit4ClassRunner,因为通过使用MyLoader你无论如何都懒惰地加载了上下文。

这些不是很好的解决方案。

更好的解决方案,代价是重构:

删除MyLoader ,不要使用单例来保留spring上下文和/或检索bean。

在应用程序的入口点初始化ClassPathXmlApplicationContext,然后在获取第一个bean之后,您不再需要ApplicationContext

对组件之间的依赖关系使用正确的自动装配/注入。而不是从MyLoader检索它们。

假设它是非Web应用程序,Web应用程序使用ContextLoaderListener加载config xml。

遵循此方法后,在使用SpringJUnit4ClassRunner加载不同的config.xml时不应该遇到任何问题,因为在运行测试时您没有从入口点运行应用程序。

每次需要弹簧组件时,您都不会MyLoader尝试延迟加载主上下文。

答案 1 :(得分:-1)

你应该真正研究使用Maven和JavaConfig。使用XML文件是2000风格,你需要更新你的风格来制作时间。看看JavaConfig和Maven,这很容易做到。