我知道我可以从src/test/resources加载文件:
1
| getClass().getResource("somefile").getFile() |
但是我怎样才能获得到src/test/resources目录的完整路径,也就是说,我不想加载文件,我只想知道目录的路径?
- 出于好奇:你为什么想知道?
- @fge需要将它传递给被测试的对象,该对象使用它来加载一个文件。
- @对于jboss,fge i有一个类似的例子--get deployment(war file)要从/etc/mycompany/deployment_name/config中读取配置的应用程序的名称(我们同时部署了许多相同应用程序的实例)。
- 直接访问资源目录是个坏主意。重构代码以在steam上操作,或者让测试首先在临时文件夹中创建一个副本。
- 不幸的是,有许多库只接受文件对象(或Hadoop路径对象),而不接受流。虽然可以简单地将测试数据复制到一个临时文件中,然后使用它,但是更容易知道路径。当然,认识到任何装在罐子里的东西都会打败它。
- @奥利弗卡尔斯沃思,我同意临时文件夹,并一直使用org.junit.rules.TemporaryFolder…但是…要从测试/资源复制,您需要知道,呃,它的路径!
- @Mikcordent——我想意思是:通过输入流读取资源,然后将其写入临时文件。
- @奥利弗卡尔斯沃思好吧…我想我明白了!
你不需要和类加载器搞混。事实上,这是一个坏习惯,因为类装入器资源在JAR存档中时不是java.io.file对象。
Maven会在运行测试之前自动设置当前工作目录,因此您只需使用:
1
| File resourcesDirectory = new File("src/test/resources"); |
如果您真的需要,resourcesDirectory.getAbsolutePath()将返回正确的值。
如果希望测试通过文件系统访问数据,我建议创建一个src/test/data目录。这就清楚了你在做什么。
- 新文件("src/test/resources/filexyz")将不起作用。无论是来自Eclipse还是来自Maven,如果您只是将其放入JUnit测试中。
- 从马文那里就可以了。在Eclipse中,您需要在测试运行程序中设置当前的工作目录,但是命令行Maven为您设置了这个目录。
- 我不这么认为。如果您只需执行"new file(getclass().getclassloader().getresource("filenamexyz.xm‌&误8203;l"),而无需设置任何内容,那么为什么要执行此操作?无论是在日食还是在马文。
- 相反,为什么不遵循构建实用程序的标准呢?尤其是当它简化了您的代码时。使用intellij或maven,不需要设置工作目录。这显然是最简单的解决方案,因为Eclipse和往常一样痛苦。
- 对于Intellij2014版本,我仍然需要更改测试方法/类的运行/调试配置中的工作目录,正如@steve c所提到的。
- @Jameswatkins我需要做什么才能正确设置?有些项目的根路径可能不同。作为一个例子,我在一个项目中工作过,如果您从intellij-idea开始测试(testng),或者从maven开始,这个代码将返回不同的结果。第一个显示根项目的resources,第二个显示实际maven模块的resources。同样的问题也发生在new File()上。
- Maven automatically sets the current working directory设置为什么?
- @Koraytugay,它将其设置为包含当前正在构建的模块的pom.xml文件的目录。
- 有同样的问题,有人能告诉我如何从"src/main/resource"路径而不是"src/test"路径访问该文件吗?对于默认路径为"src/test"的测试用例,该路径会使用"src/test"路径?
- @Jitendra,你想要文件还是资源?您试图从单元测试或在应用程序运行时访问它吗?
- @SteveC,我正试图从一个单元测试中访问src/main/resource/file中的文件。
- @jitendra,如果您想从单元测试中读取src/main/resources/data.txt,您只需使用File dataFile = new File("src/main/resources/data.txt");。
- @Steve C,我已经试过了,但它不起作用,因为当我检查时,它的绝对路径变成了src/test/src/main/resources/data.txt。
- 您是从IDE运行此测试吗?如果发生这种情况,是因为您的启动配置设置为工作目录指向src/test。
尝试使用ClassLoader类:
1 2 3
| ClassLoader classLoader = getClass (). getClassLoader();
File file = new File(classLoader. getResource("somefile"). getFile());
System. out. println(file. getAbsolutePath()); |
ClassLoader负责类中的加载。每个类都有一个对ClassLoader的引用。此代码从资源目录返回一个File。调用getAbsolutePath()返回其绝对值Path。
用于EDOCX1的javadoc〔0〕:http://docs.oracle.com/javase/7/docs/api/java/lang/classloader.html
- 这不一定是个好主意。如果资源在一个罐子里,这将导致悲伤的时刻。
- @奥利弗卡尔斯沃思,那么,如果是贾尔怎么办?
- @Anmolsinghjaggi-见我在原始问题下面的评论:)
- 使用此解决方案时,Maven生成失败
- 它也将带有文件名
我将简单地使用Java 7中的EDCOX1 4
1
| Path resourceDirectory = Paths.get("src","test","resources"); |
干净整洁!
- 这个完全相同的代码在Windows上工作吗?用于Paths.get(...)的javadoc(无论如何对我来说)表明它不会。
- @stevic您可以使用File.separator常量来构建用作路径的字符串。
- 我知道,但很难看。相比之下,new File("src/test/resources")在所有平台上都做了正确的事情。
- 为什么不直接使用Path resourceDirectory = Paths.get("src","test","resources");?
- @当然,它会使操作系统独立。随时更新答案
- 嗯,Paths.get("src","test","resources")和Paths.get("src/test/resources")在我的Windows10上工作得很好。我做错什么了?=)
- 纳沙什么都没有!/在所有已知的操作系统上工作。
如果它是一个Spring项目,我们可以使用下面的代码从src/test/resource文件夹中获取文件。
1
| File file = ResourceUtils. getFile(this. getClass(). getResource("/some_file.txt")); |
我有一个使用JUnit4.12和Java8的Maven3项目。为了获得src/test/resources下名为myxml.xml的文件的路径,我从测试用例中执行此操作:
1 2 3 4 5 6 7
| @Test
public void testApp ()
{
File inputXmlFile = new File(this. getClass(). getResource("/myxml.xml"). getFile());
System. out. println(inputXmlFile. getAbsolutePath());
...
} |
使用Intellij IDE在Ubuntu 14.04上测试。参考这里。
- 甚至与Mave3、Java 9和JUnit 5一起工作。
将src/test/resources中的所有内容复制到target/test-classes文件夹中。因此,要在Maven构建期间从测试资源中获取文件,您必须从test-classes文件夹中加载它,如下所示:
1 2 3 4 5
| 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文件夹。
原来的安华是从这个
@steve c和@ashosborne1提供的选项存在差异和限制。我相信,必须具体说明。
什么时候可以使用:File resourcesDirectory = new File("src/test/resources");?
- 1当测试只通过maven而不是通过ide运行时。
- 2.1通过Maven或
- 2.2通过IDE,只有一个项目导入到IDE中。(我使用"导入"术语,因为它用于Intellij思想。我认为Eclipse的用户也会导入他们的Maven项目)。这将有效,因为通过IDE运行测试时的工作目录与项目相同。
- 3.1通过Maven或
- 3.2通过IDE,并将多个项目导入到IDE中(当您不是学生时,通常导入多个项目),在通过IDE运行测试之前,您可以手动配置测试的工作目录。该工作目录应该引用包含测试的导入项目。默认情况下,导入到IDE中的所有项目的工作目录只有一个。可能这只是IntelliJ IDEA的限制,但我认为所有的IDE都是这样工作的。而且这种必须手动完成的配置根本不好。使用不同Maven项目中存在的几个测试,但导入到一个大型的"IDE"项目中,迫使我们记住这一点,并且不允许放松和从您的工作中获得乐趣。
@ashosborne1(我个人更喜欢这个)提供的解决方案需要2个额外的要求,这些要求必须在运行测试之前完成。以下是使用此解决方案的步骤列表:
在"src/test/resources/"中创建一个测试文件夹("teva")和文件("readme"):
src/test/resources/teva/readme文件
文件必须在测试文件夹中创建,否则将不起作用。Maven忽略空文件夹。
- 至少一次通过mvn clean install构建项目。它还将运行测试。在不构建整个项目的情况下,只通过Maven运行测试类/方法可能就足够了。因此,您的测试资源将被复制到测试类中,下面是一条路径:target/test-classes/teva/readme。
- 之后,您可以使用@ashosborne1提供的代码访问文件夹(很抱歉,我无法在项目列表中正确编辑此代码):
1 2 3
| public static final String TEVA_FOLDER ="teva"; ...
URL tevaUrl = YourTest. class. getClassLoader(). getResource(TEVA_FOLDER );
String tevaTestFolder = new File(tevaUrl. toURI()). getAbsolutePath(); |
现在,您可以通过IDE运行您的测试任意多次。直到你跑干净。它将删除目标文件夹。
在测试文件夹中创建文件并在通过IDE运行测试之前首次运行maven是必需的步骤。如果没有这些步骤,如果您只是在您的IDE中创建测试资源,然后编写测试并只通过IDE运行它,您将得到一个错误。通过MVN运行测试会将测试资源复制到目标/测试类/teva/readme中,并且类加载器可以访问这些资源。
您可能会问,为什么我需要在IDE中导入多个Maven项目,为什么要导入这么多复杂的东西?对我来说,主要的动机之一是:使与IDA相关的文件远离代码。我首先在我的IDE中创建一个新项目。这是一个伪造的项目,它只是一个与IDE相关的文件的持有者。然后,我导入已经存在的Maven项目。我强制这些导入的项目只在我原来的伪项目中保留想法文件。因此,代码中没有与IDE相关的文件。SVN不应该看到它们(请不要提供将SVN/Git配置为忽略这些文件)。而且很方便。
- 嗨,Alexander,我在target/classes和src/main/resource中遇到了资源文件的问题,您似乎是唯一一个谈论它的人。首先,我在src/main/resource上有文件,在构建项目之后,它将这些文件复制到target/classes。从这里,getClass().getClassLoader().getResource(文件名)只在目标文件夹上工作,而我想在src/main上工作。你能给我一个链接解释一下getresource文件的机制吗?如何配置资源文件夹?TKS:D
- @胡伊H&243;M H?NH,我建议不要这样做。恐怕你走错了方向。有些地方有资源文件,其他地方都知道。这样的项目更容易维护。即使对你来说,这也会更容易,你只需要了解Maven项目的结构。但可以肯定的是,您可以使用[maven.apache.org/plugins/maven resources plugin/examples/…配置默认资源位置。
- Hyyh & Sy 243;MH?NH,这里也有一个解决方案:stackoverflow.com/questions/23289098/…,但是要将您的src/main配置为一个资源…尽量避免,好像你做错了什么。
- 嗯,你能详细说明一下.gitignore出了什么问题吗?而且,IDEA在运行测试时自动运行maven(并在默认情况下设置正确的工作目录,$MODULE_DIR$)。所以在这之前不需要手动运行mvn test,从maven和idea来看,只要使用"src/test/resources/somefile.txt",一切都可以正常工作。
我使用的最简单、干净的解决方案是,假设测试类的名称是TestQuery1,并且您的test文件夹中有一个resources目录,如下所示:
1 2 3 4 5 6
| ├── java
│ └── TestQuery1.java
└── resources
└── TestQuery1
├── query.json
└── query.rq |
要获取TestQuery1的URI,请执行以下操作:
1
| URL currentTestResourceFolder = getClass (). getResource("/"+getClass (). getSimpleName()); |
要获取某个文件TestQuery1的URI,请执行以下操作:
1 2
| File exampleDir = new File(currentTestResourceFolder. toURI());
URI queryJSONFileURI = exampleDir. toURI(). resolve("query.json"); |
- 不用担心,事实上谢谢你的帮助!!好的是删除你的答案,我可以删除这个问题。是的,在这里也很沮丧,但无论如何,谢谢!!晚上好:)
在常见情况下,不能使用资源文件夹中的文件进行测试。原因是资源文件夹中的资源文件存储在JAR中。所以他们在文件系统中没有真正的路径。
最简单的解决方案可以是:
将文件从资源复制到临时文件夹,并获取该临时文件的路径。
使用临时路径进行测试。
删除临时文件。
来自JUnit的TemporaryFolder可用于创建临时文件,并在测试完成后将其删除。guava库中的类用于复制文件表单资源文件夹。
请注意,如果我们使用resources文件夹中的子文件夹,如goodone,则不必向资源路径添加前导/。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| 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 ;
}
} |
在单元测试中,使用以下方法将Hibernate与Spring一起注入:
1 2 3 4 5 6 7
| @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文件夹中。
对文件对象使用.getAbsolutePath()。
1
| getClass().getResource("somefile").getFile().getAbsolutePath() |