【问题标题】:Unable to get Maven (and Eclipse) to use test resources while testing测试时无法让 Maven(和 Eclipse)使用测试资源
【发布时间】:2012-07-01 12:31:11
【问题描述】:

我无法让单元测试使用src\test\resources 提供的资源,而不是src\main\resources 提供的资源。是的,有问题的资源在两个地方的名称相同。

我做了相当多的研究,查看了 StackOverflow 的帖子,例如:

但是这个基本问题让我很难过。

我设置了一个非常标准的 Maven Java 项目:

  • src\main下的应用源&资源
  • src\test 下的测试源和资源

Eclipse(感谢 M2Eclipse 插件)在其构建路径中包含 src\main\javasrc\main\resourcessrc\test\javasrc\test\resources

使用此设置,当我从 Eclipse 资源文件中运行我的单元测试时,src\main\resources 中的资源文件被引用。我知道为什么(因为它们在构建路径中),但我不知道如何防止它。单元测试配置面板不允许我调整(默认)类路径组件的顺序。

即使我要掩饰自己无法从 Eclipse 运行测试,Maven 也表现不佳。我可以看到processResources 步骤正在将所有测试资源复制到target\test-classes 树下。然而,当单元测试执行时,target\classes 下的资源文件的副本正在被查询。

我肯定忽略了一些显而易见的。感谢您提供的任何帮助。

[编辑] 添加更多(可能相关信息)

有问题的资源文件是一个名为persistence.xml 的文件。 Eclipselink 使用它连接到关系数据源。应用程序使用的文件版本放在src\main\resources\META-INF。 Maven 构建(比如 WAR)将 META-INF 目录放在 classes 目录下。因此 EclipseLink 工具会找到这个文件。

src/main
  |
  + -- java/com/company/ProductDao.java
  | 
  + -- resources/META-INF/persistence.xml  (Requires application container)
  |
src/test
  |
  + -- java/com/company/ProductDaoTest.java
  | 
  + -- resources/META-INF/persistence.xml  (out of container for unit tests)
  |

这里的要点是:EclipseLink 需要一个名为 persistence.xml 的文件,位于类路径上的 META-INF 目录中(是的,可以覆盖默认值,但我们不要去那里)。

因此,当 单元测试 运行时,会调用相同的应用程序逻辑。但是不能使用src\main\resources 中的文件版本。 src\test\resources 目录中提供了一个不同的版本

由于正在使用src\main\resources 中的版本,它看来我唯一的办法是在单元测试期间指示 Eclipselink 查找不同的文件名。

【问题讨论】:

  • 我很确定您可以在 src/main/resources/META-INF/persistence.xml 中创建一个新的持久性单元,您可以在单元测试和Persistence.createEntityManagerFactory 中使用它似乎无论如何,要成为您对两个 persistence.xml 文件所做的事情。
  • 同一文件中的不同持久性单元(可能)。这是一个有趣的想法。我需要弄清楚如何指示班级使用不同的持久性单元(PU)。毕竟 PU 是通过 Java 类上的注释识别的,并且(在我的情况下)是使用 Spring 连接的。感谢您的提示,我将不得不考虑一下。

标签: java eclipse unit-testing maven


【解决方案1】:

这根本不是 Maven 问题。如果您将所有内容都折叠到单个源文件夹中,您将遇到完全相同的问题。想想你真正在做什么。您的单元测试需要来自 src/main 的代码,否则它将不是该代码的单元测试。 src/main/java 和 src/main/resources 组成了您正在测试的工件。您不会混合和匹配单元测试的目录。

你基本上是这样做的:

/src/com/mycompany/myresource.txt        
/src/com/mycompany/MyAwesomeClass.java
/src/com/mycompany/myresource.txt
/src/com/mycompany/TestMyAwesomeClass.java

不要那样做。配置您的单元测试以从另一个文件加载模拟数据/您的资源文件。

我在 Maven 和 Eclipse 方面没有遇到很多问题(如果有的话)。意识到 Maven 不是魔法。如果你要使用 Maven 和 Eclipse,一切都必须由 POM 文件驱动,而不是相反。然后一切顺利。

再次澄清,您的问题与 Maven 无关。您在类路径上声明了两次资源。你需要重新考虑你的单元测试。您可以通过 Profiles 做一些事情来解决这个问题,但这是对构建系统的滥用。

【讨论】:

  • 我同意您的观点,即协同使用这些工具(“一切都必须由 POM 文件驱动”)并且不滥用构建系统。我正在努力遵守规则。然而,似乎不能依赖 工具 来设置运行测试的阶段。 测试本身必须聪明地知道使用哪个资源。我欢迎您对如何配置单元测试以加载一个但不加载另一个同名资源文件的任何建议。
  • @SriSankaran 问题不是 Maven 问题。您在类路径上的两个确切位置有两个确切的资源。没有类加载器,这是一个糟糕的设计。你能用你试图解决的特定用例来更新你的问题吗?我确信有一个更好的解决方案可以尝试将两个完全相同的资源放在类路径上。
  • 我接受这个答案,因为它解释了症状。有几种不同的“治疗方法”:在测试时只提供一个文件,将所有设置放在一个文件中并有条件地切换激活一个等。无论如何,条件切换必须在构建工具或配置文件中 不在源(或测试)代码中.
【解决方案2】:

我回答了,然后不得不花一些时间试图再次弄清楚。 在 surefire 文档中,它说 test-classes 应该是 classpath 中的第一个: http://maven.apache.org/surefire/maven-surefire-plugin/examples/configuring-classpath.html

并且肯定会显示(使用 mvn --debug 选项): [DEBUG] 测试类路径:
...\目标\测试类
...\目标\类 ....m2\repository\javax\enterprise\cdi-api\1.2\cdi-api-1.2.jar
....m2\repository\javax\el\javax.el-api\3.0.0\javax.el-api-3.0.0.jar ... 但它仍然首先使用目标\类。奇怪的是,这个错误是前段时间报告的。 然后无论我做什么,我都会先从 classes 文件夹中获取 persistence.xml。

所以我不得不在一个 persistence.xml 文件中使用两个持久性单元,这可能不是最好的,但也可以正常工作。

【讨论】:

    猜你喜欢
    • 2011-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-20
    • 2011-02-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多