我知道我可以使用以下命令从src / test / resources加载文件:
getClass().getResource("somefile").getFile()
但是,如何获得src / test / resources 目录的完整路径,即我不想加载文件,我只想知道目录的路径?
org.junit.rules.TemporaryFolder
...但是...要从测试/资源中复制,您需要知道它的路径!
我知道我可以使用以下命令从src / test / resources加载文件:
getClass().getResource("somefile").getFile()
但是,如何获得src / test / resources 目录的完整路径,即我不想加载文件,我只想知道目录的路径?
org.junit.rules.TemporaryFolder
...但是...要从测试/资源中复制,您需要知道它的路径!
Answers:
尝试与ClassLoader
班级一起工作:
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("somefile").getFile());
System.out.println(file.getAbsolutePath());
A ClassLoader
负责加载类。每个类都有对的引用ClassLoader
。此代码File
从资源目录返回a 。调用getAbsolutePath()
它会返回其absolute Path
。
适用于的Javadoc ClassLoader
:http : //docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html
您无需弄乱类加载器。实际上,这是一个坏习惯,因为当类加载器资源放在jar存档中时,它们不是 java.io.File对象。
Maven在运行测试之前会自动设置当前工作目录,因此您可以使用:
File resourcesDirectory = new File("src/test/resources");
resourcesDirectory.getAbsolutePath()
如果这正是您真正需要的,它将返回正确的值。
src/test/data
如果您希望测试通过文件系统访问数据,我建议创建一个目录。这样可以清楚地说明您在做什么。
Paths.get(...)
暗示(无论如何对我来说)它不会。
File.separator
常量来构建用作路径的字符串
new File("src/test/resources")
在所有平台上都做正确的事。
Path resourceDirectory = Paths.get("src","test","resources");
?
Paths.get("src", "test", "resources")
和Paths.get("src/test/resources")
在Windows 10的工作对我罚款。我究竟做错了什么?=)
我有一个使用JUnit 4.12和Java8的Maven3项目。为了获得一个名为myxml.xml
under 的文件的路径src/test/resources
,我从测试用例中执行以下操作:
@Test
public void testApp()
{
File inputXmlFile = new File(this.getClass().getResource("/myxml.xml").getFile());
System.out.println(inputXmlFile.getAbsolutePath());
...
}
使用IntelliJ IDE在Ubuntu 14.04上进行了测试。参考这里。
中的所有内容src/test/resources
都将复制到target/test-classes
文件夹中。因此,要在Maven构建期间从测试资源中获取文件,您必须从test-classes
文件夹中加载文件,如下所示:
Paths.get(
getClass().getProtectionDomain().getCodeSource().getLocation().toURI()
).resolve(
Paths.get("somefile")
).toFile()
分解:
getClass().getProtectionDomain().getCodeSource().getLocation().toURI()
-为您提供URI target/test-classes
。resolve(Paths.get("somefile"))
-解析someFile
到target/test-classes
文件夹。原始的anwser从这里取
@Steve C和@ ashosborne1提供的选项存在差异和约束。我认为必须指定它们。
我们File resourcesDirectory = new File("src/test/resources");
什么时候可以使用:
IntelliJ IDEA
只有一个限制,但我认为所有IDE都可以这样工作。这种必须手动完成的配置根本不好。使用不同maven项目中存在的但已导入一个大型“ IDE”项目中的多个测试,迫使我们记住这一点,并且不允许您放松身心并从工作中获得乐趣。@ ashosborne1提供的解决方案(我个人更喜欢这一点)要求在运行测试之前必须完成两个附加要求。以下是使用此解决方案的步骤列表:
在“ src / test / resources /”内部创建一个测试文件夹(“ teva”)和文件(“ readme”):
src / test / resources / teva / readme
必须在测试文件夹中创建文件,否则将无法使用。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 clean。它将删除目标文件夹。
在通过IDE运行测试之前,需要在测试文件夹中创建文件并首次运行maven。如果不执行这些步骤,如果仅在IDE中创建测试资源,然后编写测试并仅通过IDE运行它,则会出现错误。通过mvn运行测试会将测试资源复制到目标/测试类/ teva /自述文件中,并且类加载器可以访问它们。
您可能会问,为什么我需要在IDE中导入多个maven项目,为什么会有那么多复杂的东西?对我而言,主要动机之一是:使与IDA相关的文件远离代码。我首先在IDE中创建一个新项目。这是一个伪项目,只是IDE相关文件的持有者。然后,导入已经存在的Maven项目。我强迫这些导入的项目将IDEA文件仅保留在我的原始伪项目中。结果,我在代码中看不到与IDE相关的文件。SVN应该看不到它们(请不要提供将svn / git配置为忽略此类文件)。而且这只是非常方便。
.gitignore
吗?而且看起来IDEA在运行测试时会自动运行Maven(并默认设置正确的工作目录$MODULE_DIR$
)。因此,mvn test
在此之前无需手动运行,只要使用,Maven和IDEA的所有功能都可以正常运行"src/test/resources/somefile.txt"
。
我使用的最简单,干净的解决方案是,假设测试类的名称为,TestQuery1
并且文件夹中有一个resources
目录,test
如下所示:
├── java
│ └── TestQuery1.java
└── resources
└── TestQuery1
├── query.json
└── query.rq
要获取TestQuery1
do 的URI :
URL currentTestResourceFolder = getClass().getResource("/"+getClass().getSimpleName());
要获取文件之一的URI TestQuery1
,请执行以下操作:
File exampleDir = new File(currentTestResourceFolder.toURI());
URI queryJSONFileURI = exampleDir.toURI().resolve("query.json");
在常见情况下,您不能使用资源文件夹中的文件进行测试。原因是资源文件夹中的资源文件存储在jar中。因此,它们在文件系统中没有真实路径。
最简单的解决方案可以是:
TemporaryFolder
from JUnit
可用于创建临时文件,并在测试完成后将其删除。guava
库中的类用于复制文件表单资源文件夹。
请注意,如果我们在资源文件夹中使用一个子文件夹,例如good
一个子文件夹,则不必添加引号/
到资源路径。
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的Hibernate:
@Bean
public LocalSessionFactoryBean getLocalSessionFactoryBean() {
LocalSessionFactoryBean localSessionFactoryBean = new LocalSessionFactoryBean();
localSessionFactoryBean.setConfigLocation(new ClassPathResource("hibernate.cfg.xml"));
localSessionFactoryBean.setPackagesToScan("com.example.yourpackage.model");
return localSessionFactoryBean;
}
如果文件夹中没有hibernate.cfg.xml
礼物,src/test/resources
它将自动退回到文件夹中的礼物src/main/resources
。
在File对象上使用.getAbsolutePath()。
getClass().getResource("somefile").getFile().getAbsolutePath()
getFile()
返回文件实例。他说这getAbsolutePath()
是在File对象的实例上使用的。
使用Spring,您可以轻松地从resources文件夹(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;
}