spring junit为测试加载应用程序上下文

时间:2013-02-18 22:15:57

标签: spring junit applicationcontext

我的WEB-INF目录下有一些XML文件:

  • lyricsBaseApp-servlet.xml中
  • hibernate.xml
  • dataSource.xml
  • 的beans.xml

servlet xml导入其他xml文件:

<import resource="dataSource.xml"/>
<import resource="hibernate.xml"/>
<import resource="beans.xml"/>

我希望我的junit4 JukeboxTest类包含整个弹簧配置。使用默认文件名我创建了一个JukeboxTest-content.xml文件。最后,我不知道该放什么......

我试过了:

<import resource="/WEB-INF/dataSource.xml"/>
<import resource="/WEB-INF/hibernate.xml"/>
<import resource="/WEB-INF/beans.xml"/>

<import resource="classpath:./WEB-INF/dataSource.xml"/>
<import resource="classpath:./WEB-INF/hibernate.xml"/>
<import resource="classpath:./WEB-INF/beans.xml"/>

和其他一些想法但都失败了。有人能指出我如何访问这些文件以及spring解释这些文件路径的方式是什么?

2 个答案:

答案 0 :(得分:82)

选项1 (应该首选,因为这是最佳做法):
重构WEB-INF下的配置文件,并将公共部分(您也想从集成测试中访问)移动到src/main/resources/。然后在src/test/resources/中编写测试特定的配置文件(如果您只需要从src/main导入几个不同的配置文件来汇总测试上下文,那么跳过这个,最好使用@ContextConfiguration。< / p>

选项2 (黑客):
使用以下参考文献:

@ContextConfiguration("file:src/main/webapp/WEB-INF/dataSource.xml")

选项3 (黑客):
如果您有Maven项目,则可以配置maven-surefire-plugin(在测试阶段使用)在测试执行期间将src/main/webapp声明为附加的classpath元素。

后两个选项被视为黑客,因为src/main/webapp下的文件根本不应该在类路径上。

现在详细说明:

您不能将这些文件称为classpath:/WEB-INF/*.xml的原因是它们确实不在类路径中。了解您的webapp如何打包以及最终在类路径上的结果非常重要。假设默认的Maven项目结构:

  1. 编译后src/main/java的Java类转到/WEB-INF/classes
  2. 来自src/main/resources的资源也会转到/WEB-INF/classes
  3. 项目依赖关系转到/WEB-INF/lib
  4. src/main/webapp中的所有内容都转到/(包的根目录)。这意味着,src/main/webapp/WEB-INF的所有文件都会转到/WEB-INF
  5. 最重要的是要知道,类路径只包含/WEB-INF/classes/WEB-INF/lib中每个jar的一个条目。因此,这两个位置之外的资源对于类加载器是完全不可见的。对于直接在 /WEB-INF下的xml配置文件也是如此,这就是参考classpath:/WEB-INF/dataSource.xml永远无法工作的原因。

    你可能会问自己,如果从类路径无法访问这些xml配置文件,那么它们到底是怎么回事?答案很简单:当您启动webapp(而不是仅执行单元/集成测试)时,它在Servlet容器中运行,该容器提供对ServletContext(来自Servlet API的实际类)的访问,因此它使用ServletContext.getResourceAsStream()来加载这些文件。理解的关键是来自此方法的javadoc的以下引用:

      

    此方法与使用类加载器的java.lang.Class.getResourceAsStream不同。此方法允许servlet容器从任何位置为servlet提供资源,而无需使用类加载器。

    对不起,这太长了,但这就是整个故事......

答案 1 :(得分:12)

试试这个

@ContextConfiguration(locations = {"classpath:**/dataSource.xml",
                               "classpath:**/hibernate.xml", 
                               "classpath:**/WEB-INF/beans.xml"})