如何在JUnit中获取src/test/resources目录的路径?

我知道我可以从src/test/resources加载一个文件:

getClass().getResource("somefile").getFile()

但是我怎么能得到src/test/resources 目录的完整路径,即我不想加载一个文件,我只想知道目录的路径?

475073 次浏览

尝试使用ClassLoader类:

ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("somefile").getFile());
System.out.println(file.getAbsolutePath());

ClassLoader负责类中的加载。每个类都有一个ClassLoader的引用。这段代码从资源目录返回File。在它上调用getAbsolutePath()将返回它的绝对Path

ClassLoader: http://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html的Javadoc

你不需要干扰类加载器。事实上,这是一个坏习惯,因为类装入器资源在jar存档中时是 java.io.File对象。

Maven在运行测试之前自动设置当前工作目录,因此您可以使用:

    File resourcesDirectory = new File("src/test/resources");

resourcesDirectory.getAbsolutePath()将返回正确的值,如果这是你真正需要的。

如果你想让你的测试通过文件系统访问数据,我建议创建一个src/test/data目录。这让你清楚地知道你在做什么。

我有一个使用JUnit 4.12和Java8的Maven3项目。 为了获得src/test/resources下名为myxml.xml的文件的路径,我从测试用例中执行以下操作:

@Test
public void testApp()
{
File inputXmlFile = new File(this.getClass().getResource("/myxml.xml").getFile());
System.out.println(inputXmlFile.getAbsolutePath());
...
}
在Ubuntu 14.04上用IntelliJ IDE测试。 参考在这里。< / p >

请注意

前面的/符号是必要的,因为Class.getResource(String)不一定会和FileNotFoundException一起显示整个文件路径(缺失)。

@Steve C和@ashosborne1提供的选项存在差异和限制。我想,它们必须具体说明。

什么时候我们可以使用:File resourcesDirectory = new File("src/test/resources");?

  • 当测试只通过maven而不是IDE运行时。
  • 2.1何时通过maven或
  • 2.2通过IDE,只有一个项目导入IDE。(我使用“导入”术语,因为它在IntelliJ IDEA中使用。我认为eclipse的用户也导入了他们的maven项目)。这将工作,因为当您通过IDE运行测试时,工作目录与您的项目相同。
  • 3.1何时通过maven或
  • 在你通过IDE运行测试之前,你手动配置你的测试的工作目录。该工作目录应指向包含测试的导入项目。默认情况下,导入IDE的所有项目的工作目录只有一个。可能这只是IntelliJ IDEA的限制,但我认为所有ide都是这样工作的。而这种必须手动完成的配置,一点也不好。使用不同的maven项目中存在的几个测试,但导入到一个大的“IDE”项目中,迫使我们记住这一点,不允许放松和从工作中获得乐趣。

@ashosborne1提供的解决方案(我个人更喜欢这个)需要在运行测试之前完成2个额外的要求。下面是使用这个解决方案的步骤列表:

  • 在“src/test/resources/”中创建一个测试文件夹(“teva”)和文件(“readme”):

    src /测试/资源/ teva / readme

    必须在test文件夹中创建文件,否则将无法工作。Maven忽略空文件夹。

  • 至少一次通过mvn clean install构建项目。它还将运行测试。通过maven只运行您的测试类/方法就足够了,而不需要构建整个项目。因此,您的测试资源将被复制到测试类中,这里有一个路径:target/test-classes/teva/readme

  • 在此之后,您可以使用代码访问文件夹,已经由@ashosborne1提供(对不起,我无法在此项目列表中正确编辑此代码):

public static final String TEVA_FOLDER = "teva"; ...
URL tevaUrl = YourTest.class.getClassLoader().getResource(TEVA_FOLDER);
String tevaTestFolder = new File(tevaUrl.toURI()).getAbsolutePath();

现在您可以通过IDE运行您的测试,次数不限。直到你把mvn清理干净。它将删除目标文件夹。

在通过IDE运行测试之前,在测试文件夹中创建文件并首次运行maven是必需的步骤。如果没有这些步骤,如果您只是在IDE中创建测试资源,然后编写测试并仅通过IDE运行它,您将会得到一个错误。通过mvn运行测试会将测试资源复制到target/test-classes/teva/readme中,并且类加载器可以访问这些资源。

您可能会问,为什么我需要在IDE中导入多个maven项目,为什么有这么多复杂的东西?对我来说,主要动机之一是:让与ida相关的文件远离代码。我首先在IDE中创建一个新项目。这是一个假项目,只是一个ide相关文件的持有者。然后,导入已经存在的maven项目。我强制这些导入的项目只保留我原来的假项目中的IDEA文件。因此,我在代码中看不到与ide相关的文件。SVN不应该看到这些文件(请不要配置SVN /git忽略这些文件)。而且它非常方便。

如果这是一个spring项目,我们可以使用下面的代码从src /测试/资源文件夹中获取文件。

File file = ResourceUtils.getFile(this.getClass().getResource("/some_file.txt"));

我将简单地使用Java 7中的Path

Path resourceDirectory = Paths.get("src","test","resources");

干净利落!

我使用的最简单和干净的解决方案,假设测试类的名称是TestQuery1,并且在你的test文件夹中有一个resources目录,如下所示:

├── java
│   └── TestQuery1.java
└── resources
└── TestQuery1
├── query.json
└── query.rq

要获得TestQuery1的URI,请执行以下操作:

URL currentTestResourceFolder = getClass().getResource("/"+getClass().getSimpleName());

要获取文件TestQuery1的URI,请执行以下操作:

File exampleDir = new File(currentTestResourceFolder.toURI());
URI queryJSONFileURI = exampleDir.toURI().resolve("query.json");

在File对象上使用. getabsolutepath()。

getClass().getResource("somefile").getFile().getAbsolutePath()

使用以下命令在单元测试中注入Hibernate和Spring:

@Bean
public LocalSessionFactoryBean getLocalSessionFactoryBean() {
LocalSessionFactoryBean localSessionFactoryBean = new LocalSessionFactoryBean();
localSessionFactoryBean.setConfigLocation(new ClassPathResource("hibernate.cfg.xml"));
localSessionFactoryBean.setPackagesToScan("com.example.yourpackage.model");
return localSessionFactoryBean;
}

如果你的src/test/resources文件夹中没有hibernate.cfg.xml,它会自动回到你的src/main/resources文件夹中。

src/test/resources中的所有内容都复制到target/test-classes文件夹中。所以在maven构建期间,要从测试资源中获取文件,你必须从test-classes文件夹中加载它,就像这样:

Paths.get(
getClass().getProtectionDomain().getCodeSource().getLocation().toURI()
).resolve(
Paths.get("somefile")
).toFile()

分解:

  1. getClass().getProtectionDomain().getCodeSource().getLocation().toURI() -给你target/test-classes的URI。
  2. resolve(Paths.get("somefile")) -解析someFiletarget/test-classes文件夹。

原始答案取自

在一般情况下,不能将资源文件夹中的文件用于测试。原因是资源文件夹中的资源文件存储在jar中。它们在文件系统中没有真正的路径。

最简单的解决方法是:

  1. 将文件从资源复制到临时文件夹,并获取该临时文件的路径。
  2. 使用临时路径执行测试。
  3. 删除临时文件。

来自JUnitTemporaryFolder可以用来创建临时文件,并在测试完成后删除它。guava库中的类用于从资源文件夹中复制文件。

请注意,如果我们使用resources文件夹中的子文件夹,比如good one,我们不必在资源路径中添加前导/

public class SomeTest {


@Rule
public TemporaryFolder tmpFolder = new TemporaryFolder();




@Test
public void doSomethinge() throws IOException {
File file = createTmpFileFromResource(tmpFolder, "file.txt");
File goodFile = createTmpFileFromResource(tmpFolder, "good/file.txt");


// do testing here
}


private static File createTmpFileFromResource(TemporaryFolder folder,
String classLoaderResource) throws IOException {
URL resource = Resources.getResource(classLoaderResource);


File tmpFile = folder.newFile();
Resources.asByteSource(resource).copyTo(Files.asByteSink(tmpFile));
return tmpFile;
}


}

使用Spring,你可以很容易地从资源文件夹(main/resources或test/resources)中读取:

例如,创建一个文件:test/resources/subfolder/sample.json

@Test
public void testReadFile() {
String json = this.readFile("classpath:subfolder/sample.json");
System.out.println(json);
}


public String readFile(String path) {
try {
File file = ResourceUtils.getFile(path);
return new String(Files.readAllBytes(file.toPath()));
} catch (IOException e) {
e.printStackTrace();
}


return null;
}
List<String> lines = Files.readAllLines(Paths.get("src/test/resources/foo.txt"));
lines.forEach(System.out::println);

在Spring中,你可以这样使用:

import org.springframework.core.io.ClassPathResource;


// Don't worry when use a not existed directory or a empty directory
// It can be used in @before
String dir = new ClassPathResource(".").getFile().getAbsolutePath()+"/"+"Your Path";

你可以去你想去的地方

new File(".").getAbsolutePath()

则可以导出src/test/resources
的路径 通常是

new File("src/test/resources")

哇,正确答案还不在这里!

MyClass.class.getResource("/somefile");
MyClass.class.getResourceAsStream("/somefile");

https://javachannel.org/posts/how-to-access-static-resources/