为什么在测试方法开始之前文件不存在时 getResourceAsStream() return 为空?

Why does getResourceAsStream() return null when File does not exist before start of Test method?

在将其标记为重复之前,请阅读问题!

我有一个 JUnit 测试,它测试将结果写入 file 的方法。要检查结果,我想读取该结果文件并检查其内容。

问题是当结果文件在测试开始前不存在时,方法getResourceAsStream() returns null.

我的测试代码是这样的:

@Inject
private ObjectToTest obj

@Test
public void testMethod() throws Exception {
    // Do some setup (inject mocks, set properties of obj, ...)

    obj.method(); // <-- Creates result.txt
    Mockito.verify(obj).method();

    // Thread.sleep(1000); <-- I have tried to use this to wait some time for the result, but it did not work

    // This part is null on the first run of the test
    // When I run the test the second time, the file does already exist and it returns the right InputStream for the File
    InputStream resultInp = this.getClass().getResourceAsStream("/test-out/result.txt");

    String resultStr = IOUtils.toString(resultInp, "UTF-8");

    assertThat(resultStr).isNotNull();
    assertThat(resultStr.split("\n")).hasSize(5);
}

是否有任何解释为什么会发生这种情况,或者它必须对代码的另一部分做些什么?

我在 Whosebug 上没有找到任何关于这个问题的信息,但如果我错了,请指导我正确 post。

getResourceAsStream() 方法 returns 类路径上资源的流,使用由类加载器缓存的目录/索引信息。如果在缓存类路径后将资源添加到类路径上的某个目录树或存档,类加载器可能不会 "see" it1.

这很可能就是您的测试代码中发生的情况。

Java 应用程序不应将类加载器资源视为通用文件系统。相反,使用 FilePath 来表示文件,并使用 FileInputStream 或类似的方式打开它们。


1 - ClassLoader 等的 javadoc 中似乎没有指定实际行为。我的描述基于一些 Java 实现的观察/报告行为。