How to read a text-file resource into Java unit test?
我有一个单元测试需要使用位于src/test/resources/abc.xml中的XML文件。把文件的内容放到String中最简单的方法是什么?
- 另外,stackoverflow.com/questions/1656797/…
- @尼基塔,尽管我的回答是肯定的,但这些问题并没有提到我认为是正确解决OP问题的方法的getResourceAsStream()。
- @kirk,getresourceasstream将文件缓存在类加载器中。这是不必要的。
- @Thorbj&248;rn,你的参考资料在哪里?在任何情况下,它肯定是方便和便携的,这实际上是必要的。
- 有关Android Studio,请参阅以下链接stackoverflow.com/a/33057561/3256989
- 耶戈尔256的回答不起作用。我的情况是getClass().getClassLoader().getResource("com/example/ninja.txt"));,我的资源文件位于com/example/ninja.txt。
最后,我找到了一个简洁的解决方案,这要归功于ApacheCommons:
1 2 3 4 5 6 7 8 9 10 11
| package com.example;
import org.apache.commons.io.IOUtils;
public class FooTest {
@Test
public void shouldWork () throws Exception {
String xml = IOUtils. toString(
this. getClass(). getResourceAsStream("abc.xml"),
"UTF-8"
);
}
} |
工作得很好。文件src/test/resources/com/example/abc.xml已加载(我正在使用maven)。
如果将"abc.xml"替换为,例如,"/foo/test.xml",则将加载此资源:src/test/resources/foo/test.xml。
你也可以使用仙人掌:
1 2 3 4 5 6 7 8 9 10 11
| package com.example;
import org.cactoos.io.ResourceOf;
import org.cactoos.io.TextOf;
public class FooTest {
@Test
public void shouldWork () throws Exception {
String xml = new TextOf (
new ResourceOf ("/com/example/abc.xml") // absolute path always!
). asString();
}
} |
- 可以简单地做到这一点,而不需要外部的库依赖。
- 在这种情况下,我们应该关闭inputstream吗?
- @DBF好问题…我认为我们应该这样做,但是因为这是一个单元测试,我们并不真正关心:)
- 您存储"abc.xml"的路径是什么?
- @Bennyneugebauer查看答案的更新
- @是的,256因为它是一个单元测试关闭资源特别重要。"单元测试应该是快速且独立的,让资源在测试运行期间保持开放状态,这意味着您的测试运行速度最好较慢,最坏的情况是以难以诊断的方式失败。
- 同样紧凑,但适当关闭输入流:IOUtils.toString(this.getClass().getResource("foo.xml"), "UTF-8")。
- 嘿@yegor256,不是IOUtils.toString静态方法吗?你现在怎么解决这个问题呢,根据你所熟知的"不喜欢"的说法?
- @ RadekPosto?我无论如何也不能解决它,因为我从Apache得到的只是这个静态方法。如果他们能提供,比如FileAsString类,那就太好了,用哪个构造函数代替这个静态方法
- 以防getClass().getResourceAsstream()给出空指针。尝试从thread.currentThread().getContextClassLoader().getResourceas‌&8203;stream….
- 只有当文件位于同一个包中时,此操作才有效。如果它们不在同一个包里呢
- @ RadekPosto?要解决我创建cactoos的问题,请参阅更新后的答案:)
- 我必须使用绝对路径,否则getResource()会返回null。所以这对我来说是正确的:this.getClass().getResource("/my-test-file.txt")。
- 这对我来说很有用。
直截了当地说:
1 2
| ClassLoader classLoader = getClass (). getClassLoader();
File file = new File(classLoader. getResource("file/test.xml"). getFile()); |
- 在使用JUnit测试时为我工作,并希望通过将XLS文件加载到byte[]格式来设置测试。
- 这应该是被接受的答案->WorkforMeonSpringBoot刚刚在resources文件夹后面添加了路径。
- 这绝对是正确的答案。
- 按预期工作。未使用外部库。
- OP询问"什么是将文件内容转换成字符串最简单的方法?"如果直接回答这个问题,这个答案会更好。
- getClass().getClassLoader().getResource("test.xml");
- file file=new file(getclass().getresource("/responses/example.json").getfi‌&8203;le())在没有getclassloader()的情况下也可以正常工作。
假设文件中有UTF8编码-如果没有,只需去掉"utf8"参数&;将使用每种情况下底层操作系统的默认字符集。
JSE 6中的快速方法-简单&无第三方库!
1 2 3 4 5 6 7 8
| import java.io.File;
public class FooTest {
@Test public void readXMLToString () throws Exception {
java. net. URL url = MyClass. class. getResource("test/resources/abc.xml");
//Z means:"The end of the input but for the final terminator, if any"
String xml = new java. util. Scanner(new File(url. toURI()), "UTF8"). useDelimiter("\\Z"). next();
}
} |
JSE 7中的快速方法(未来)
1 2 3 4 5 6
| public class FooTest {
@Test public void readXMLToString () throws Exception {
java. net. URL url = MyClass. class. getResource("test/resources/abc.xml");
java. nio. file. Path resPath = java. nio. file. Paths. get(url. toURI());
String xml = new String(java. nio. file. Files. readAllBytes(resPath ), "UTF8");
} |
不过,这两个都不打算放大量的文件。
- 第二个示例不起作用,readallbytes似乎不接受url…我最能让它工作的是String xml = new String(java.nio.file.Files.readAllBytes(Paths.get(url.toURI())),"UTF8");。
- 它确实有效-需要一个path类型的参数。所以我叫它呼吸。:)
- 哦,对了:)哦
- 我错过什么了吗?创建变量url而不使用它,使用变量resPath而不创建它。似乎很重要的一点是要包括让它发挥作用的魔法。
- Oop。已修复-已添加缺少的行。现在我明白了之前在评论中的困惑:-$
- @格伦贝斯特-你能解释一下"巨大的档案"是什么吗?
- 上面将文件内容直接读取到内存中的字符串中。因此,例如,如果您有4GB的内存,那么一个介于1-4GB之间的文件可能会被归类为"巨大的",因为它将消耗大量的内存资源(除了页面交换到磁盘)。对于大文件,最好以块形式进行流式读取,而不是同时进行。
- java7版本是完美的,提示:使用standardcharsets.utf_8来避免不受支持的编码异常
- 你能解释一下为什么你要使用MyClass而不是FoTest,以及什么时候你想使用哪个类吗?
- 在示例中添加完整的包名称做得很好。这总是有帮助的。
- 我用文件名MyClass.class.getResource("/test/resources/abc.xml")开头的斜线
首先确保将abc.xml复制到输出目录。那么您应该使用getResourceAsStream():
1 2
| InputStream inputStream =
Thread. currentThread(). getContextClassLoader(). getResourceAsStream("test/resources/abc.xml"); |
一旦有了inputstream,就只需要将其转换为字符串。这个资源说明了这一点:http://www.kodejava.org/examples/266.html。不过,我将摘录相关代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| |
- 什么是your output directory?
- @文森佐,通常是"班",也许是"宾"。也就是说,无论你在哪里编译你的类。大多数IDE已经将资源文件(如XML文件)复制到该目录,所以您可能需要快速达到峰值,看看它是否已经存在。
- 在您的案例中似乎有太多的代码。我最好用一些apache.commons.io.*类来读取文件,用java.lang.Class.getResource()类。你怎么认为?
- 测试它的一个好方法是,将测试用例写在一个testkey=value的".properties"文件中,然后直接加载inputstream。示例:properties properties=new properties();properties.load(inputstream);string testcase=properties.getproperty("testkey");
- 如何将abc.xml复制到输出目录?@ KirkWoll
使用google guava:
1 2 3 4 5 6 7 8 9 10
| import com.google.common.base.Charsets;
import com.google.common.io.Resources;
public String readResource (final String fileName, Charset charset ) throws Exception {
try {
return Resources. toString(Resources. getResource(fileName ), charset );
} catch (IOException e ) {
throw new IllegalArgumentException(e );
}
} |
例子:
1
| String fixture = this. readResource("filename.txt", Charsets. UTF_8) |
您可以尝试执行以下操作:
1 2
| String myResource = IOUtils. toString(this. getClass(). getResourceAsStream("yourfile.xml")). replace("
", ""); |
- 你为什么要拆掉新品?
- @祖杜兹,对不起,我不记得了,这是两年前的事了
- ioutils.toString toString(stream)也不推荐使用。需要在ioutils.toString toString(stream,charsets.utf_8)中传递字符集(import com.google.common.base.charsets;)
可以使用JUnit规则为测试创建此临时文件夹:
@Rule public TemporaryFolder temporaryFolder = new TemporaryFolder();
File file = temporaryFolder.newFile(".src/test/resources/abc.xml");
下面是我用来获取文本文件的内容。我使用了公共资源的ioutils和guava的资源。
1 2 3 4 5
| public static String getString (String path ) throws IOException {
try (InputStream stream = Resources. getResource(path ). openStream()) {
return IOUtils. toString(stream );
}
} |