【问题标题】:spring junit load application context for tests用于测试的 spring junit 加载应用程序上下文
【发布时间】:2013-02-03 11:22:08
【问题描述】:

我的 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 以什么方式解释这些文件路径?

【问题讨论】:

    标签: spring junit applicationcontext


    【解决方案1】:

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

    选项 2(破解):
    使用如下引用:

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

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

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

    现在详细解释:

    您不能将这些文件称为classpath:/WEB-INF/*.xml 的原因是它们确实不在类路径中。了解您的 web 应用程序是如何打包的,以及类路径中的最终结果是什么,这一点很重要。假设一个默认的 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

    要知道的最重要的事情是类路径将只包含/WEB-INF/classes/WEB-INF/lib 中每个jar 的一个条目。因此,这两个位置之外的资源对于类加载器来说是完全不可见的。这对于 直接位于 /WEB-INF 下的 xml 配置文件也是如此,这就是为什么引用 classpath:/WEB-INF/dataSource.xml 永远不会起作用的原因。

    您可能会问自己,如果这些 xml 配置文件无法从类路径访问,那么这些 xml 配置文件是如何被 Spring 加载的呢?答案很简单:当你启动你的 web 应用程序(而不是只执行单元/集成测试)时,它运行在一个 Servlet 容器中,它提供对ServletContext(来自 Servlet API 的一个实际类)的访问,所以它使用ServletContext.getResourceAsStream() 加载这些文件。理解的关键是下面这个方法的javadoc的引用:

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

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

    【讨论】:

    • 如何引用src/test/resources中的上下文文件? @Kris 的答案是唯一对我有用的答案。
    • 选择选项 1 .. 然后您如何实际加载该上下文文件?
    • @zagyi 如何将 src/main/webapp 声明为测试上下文中的附加类路径之一?
    【解决方案2】:

    试试这个

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

    【讨论】:

    • 这对我来说适用于 src/test/resources 中的 application-context.xml。
    猜你喜欢
    • 2018-07-11
    • 2015-04-27
    • 2013-02-08
    • 2021-06-23
    • 2012-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-17
    相关资源
    最近更新 更多