【发布时间】:2011-11-28 15:02:19
【问题描述】:
我在运行以下代码时遇到问题:
configService.setMainConfig("src/test/resources/MainConfig.xml");
从 Junit @Before 方法中。
这是 Maven 构建其目标文件夹的方式吗?
【问题讨论】:
我在运行以下代码时遇到问题:
configService.setMainConfig("src/test/resources/MainConfig.xml");
从 Junit @Before 方法中。
这是 Maven 构建其目标文件夹的方式吗?
【问题讨论】:
直接访问MainConfig.xml。 src/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().
【讨论】:
getClass().getResource("/MainConfig.xml").getFile()
我猜setMainConfig 期望资源的路径,它将使用 ClassLoader 加载,而不是相对文件路径。如果您链接到这个神秘的 configService.setMainConfig 方法的 javadoc 会有所帮助。
如果我的猜测是正确的,那么路径应该只是 MainConfig.xml。 Mave 将src/test/resources 的内容复制到target/test-classes (IIRC) 文件夹。这个 test-classes 文件夹位于单元测试的类路径中。
【讨论】:
我今天遇到了同样的问题,我已经找到了一些解决方案。
首先,这是我的文件结构:
.
└── 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)。
来源:
【讨论】: