Manu Artero
Manu Artero

Reputation: 10303

Write a file in a JUnit test under resources folder

I'd already tried with this stack overflow question but I'm a little bit lost with maven.

In a Maven project I want to test a function which finally writes a text file in the given path. The signature of my function is boolean printToFile(String absolutePath) (the returning value is a success flag)

Under src/test/resources I have my expected file; lets call it expected.txt.

Using the apache.commons.commons-io dependency:

<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-io</artifactId>
  <version>1.3.2</version>
</dependency>

I want to call my function; create two File objects and compare their content:

@Test
public void fileCreationTest() {
  String outputPath = Thread.currentThread().getClass().getClassLoader().getResource("got.txt").getFile();
  myTestedObject.printToFile(outputPath);
  File got = new File(outputPath);

  String expectedFilePath = Thread.currentThread().getClass().getClassLoader().getResource("expected.txt").getFile();
  File expected = new File(expectedFilePath)

  boolean areEqual = FileUtils.contentEquals(got, expected);
  Assert.assertTrue(areEqual);

[EDITED]
It's not a matter of the calling function: If I call it from normal code, it does work But If I run my test, it fails (from maven or from my IDE). I think it's something related with the test nature.

Upvotes: 3

Views: 10919

Answers (1)

Harald K
Harald K

Reputation: 27113

The following code makes no sense to me (in a test or otherwise):

String outputPath = Thread.currentThread().getClass().getClassLoader().getResource("got.txt").getFile();
myTestedObject.printToFile(outputPath);
File got = new File(outputPath);

The problem is that getResource will return a URL to a resource that might be on the file system, in a JAR or other place. And it must exist for getResource to return non-null. That means your test will need to overwrite it (and it is probably not writable).

What you probably should do instead, is:

File got = File.createTempFile("got-", ".txt");
String outputPath = got.getAbsolutePath();
myTestedObject.printToFile(outputPath);

Also, for the expected file, I think it's better if you use the test class' class loader, rather than the context class loader. It's also more readable:

String expectedFilePath = getClass().getClassLoader().getResource("expected.txt").getFile();
File expected = new File(expectedFilePath);

However, again you make the assumption that the resource is loaded from the file system. So it might break if it isn't. Can you compare the bytes from two InputStreams instead?

Finally, make sure that the test writes the file with the same encoding as the your expected file, and that linefeeds/carriage returns match.

Upvotes: 4

Related Questions