0

Before flagging this as a duplicate please read the question!

I have a JUnit Test which tests a method that writes its result in a file. To check the result I want to read that result file and check its content.

The problem is that when the result file does not already exist before the start of the test, the method getResourceAsStream() returns null.

My code for the Test is something like this:

@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);
}

Is there any explanation to why this happens or must it have to do something with another part of the code?

I have not found anything regarding this issue on StackOverflow, but if I am wrong please guide me to the right post.

MauriceNino
  • 6,214
  • 1
  • 23
  • 60

1 Answers1

3

The getResourceAsStream() method returns a stream for a resource on the classpath, using directory / index information that is cached by the classloader. If you add a resource to some directory tree or archive on the classpath after the classpath has been cached, the classloader is likely to not "see" it1.

That is most likely is what has happened in your test code.

A Java application should not be trying to treat classloader resources like a general purpose file system. Instead, use File or Path to denote files, and FileInputStream or similar to open them.


1 - The actual behavior does not appear to be specified in the javadocs for ClassLoader, etcetera. My description is based on the observed / reported behavior of some Java implementations.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216