【问题标题】:Why Can't I access src/test/resources in Junit test run with Maven?为什么我无法在使用 Maven 的 Junit 测试运行中访问 src/test/resources?
【发布时间】:2011-11-28 15:02:19
【问题描述】:

我在运行以下代码时遇到问题:

configService.setMainConfig("src/test/resources/MainConfig.xml");

从 Junit @Before 方法中。

这是 Maven 构建其目标文件夹的方式吗?

【问题讨论】:

    标签: java junit4 mockito


    【解决方案1】:

    直接访问MainConfig.xmlsrc/test/resources 目录内容放置在 CLASSPATH 的根目录中。

    更准确地说:src/test/resources 的内容被复制到target/test-classes,所以如果你有以下项目结构:

    .
    └── src
        └── test
            ├── java
            │   └── foo
            │       └── C.java
            └── resources
                ├── a.xml
                └── foo
                    └── b.xml
    

    它将产生以下测试 CLASSPATH 内容:

    • /foo/C.class
    • /a.xml
    • /foo/b.xml

    要真正从 Java 源访问文件,请使用 getClass().getResource("/MainConfig.xml").getFile().

    【讨论】:

    • 感谢您的简洁回答。您确实是正确的,该文件可以在 /target/test-classes 下看到。但是,我仍然无法从我的代码中引用它。尝试了各种组合:'configService.setMainConfig("MainConfig.xml"); ' 'configService.setMainConfig("target/test-classes/MainConfig.xml"); ' configService.setMainConfig("classpath:MainConfig.xml");等等等等
    • 试试getClass().getResource("/MainConfig.xml").getFile()
    • 如果你使用 Tycho 和 eclipse-plugin 作为打包类型,别忘了在 build.properties 文件中添加 src/test/resources。
    • 谢谢,但我在 jenkins 中运行我的 junit,它失败了,由于某种原因,来自 src/test/resource 的文件被复制到 /target/classes 而不是 /target/test-classes跨度>
    【解决方案2】:

    我猜setMainConfig 期望资源的路径,它将使用 ClassLoader 加载,而不是相对文件路径。如果您链接到这个神秘的 configService.setMainConfig 方法的 javadoc 会有所帮助。

    如果我的猜测是正确的,那么路径应该只是 MainConfig.xml。 Mave 将src/test/resources 的内容复制到target/test-classes (IIRC) 文件夹。这个 test-classes 文件夹位于单元测试的类路径中。

    【讨论】:

    • 谢谢。你的逻辑是正确的(见上面的评论)但不幸的是我仍然无法让它工作
    【解决方案3】:

    我今天遇到了同样的问题,我已经找到了一些解决方案。

    首先,这是我的文件结构:

    .
    └── src
    │   └── test
    │       ├── java
    │       │   └── mypackage
    │       │       └── MyClassTest.java
    │       └── resources
    │           └── image.jpg
    └── target
        └── test-classes
                ├── image.jpg
                └── mypackage
                    └── MyClassTest.class  
    

    什么不起作用:(Java 11 合成器)

    var imgFile = new File("image.jpg"); // I was expecting that Junit could find the file.
    var absPath = file.getAbsolutePath(); // /home/<user>/../<project-root>/image.jpg
    var anyFileUnderThisPath = file.exists(); // false
    

    我们可以注意到,绝对路径根本没有指向我的图像!但是,如果我在项目根目录下有一个图像,那么它就可以工作了。

    解决方案 1:路径(在 Java 7 中引入)

    var relPath = Paths.get("src", "test", "resources", "image.jpg"); // src/test/resources/image.jgp
    var absPath = relPath.toFile().getAbsolutePath(); // /home/<user>/../<project-root>/src/test/resources/image.jpg
    var anyFileUnderThisPath = new File(absPath).exists(); // true
    

    如我们所见,它指向正确的文件。

    解决方案 2:类加载器

    var classLoader = getClass().getClassLoader();
    var url = classLoader.getResource("image.jpg"); // file:/home/<user>/../<project-root>/target/test-classes/image.jpg
    var file = new File(url.getFile()); // /home/<user>/../<project-root>/target/test-classes/image.jpg
    var anyFileUnderThisPath = file.exists(); // true
    

    注意现在是在目标目录下搜索文件!并且有效。

    解决方案 3:文件(非工作示例的改编)

    var absPath = new File("src/test/resources/image.jpg").getAbsolutePath();
    var var anyFileUnderThisPath = new File(absPath).exists(); // true
    

    在采用绝对路径并将src/test/resources/ 作为前缀之后也可以使用。

    总结

    所有三个解决方案都有效,但我认为必须输入 src/test/resources/ 并不优雅,这就是为什么我更喜欢第二种解决方案 (ClassLoader)。

    来源:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-26
      • 2015-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多