2

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

一个简单的例子是:

mainConfig.xml

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

测试配置.xml

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

我处理应用程序上下文的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)。这将导致冲突,因为这两个文件不同。

在不会发生这种不匹配的情况下,将所有这些连接起来的正确方法是什么?

4

2 回答 2

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/s 之后,您不再需要ApplicationContext了。

对组件之间的依赖关系使用适当的自动装配/注入。而不是从MyLoader.

假设它是一个非 Web 应用程序,因为 Web 应用程序用于ContextLoaderListener加载配置 xml。

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

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

于 2013-03-21T22:51:35.223 回答
-1

你真的应该考虑使用 Maven 和 JavaConfig。使用 XML 文件是 2000 年的风格,你需要更新你的风格以适应时代。看看 JavaConfig 和 Maven,这很容易做到。

于 2013-03-21T13:10:03.480 回答