I have a java Spring Boot application that looks for files in an Unprocessed directory, processes the file, then moves it to a Processed directory. I am trying to write an integration test in using JUnit that tests whether or not the move is successful.
To do this, I have created a sub-directory tree within src/test/resources
that mirrors the directories on the servers. This way the test is not bound to any single computer or server.
When I try to run the test, I get the java.nio.file.DirectoryNotEmptyException
.
Below is the entire text of my integration test. The idea is that I have a test file test_file.csv
that permanently lives in my src/test/resources
directory. For the integration test, I want to make a copy of that file, and write it to src/test/resources/foo/bar/Unprocessed
. If the move logic being tested works, test_file.csv
should end up in the src/test/resources/foo/bar/Processed
folder. Both the Processed
and Unprocessed
directories are empty at the start of the test.
How can I make this test not error? Thanks in advance.
@Test
public void processAndMoveSuccessTest() throws IOException {
File originalFileLocation = ResourceUtils.getFile("classpath:test_file.csv");
System.out.println(originalFileLocation.getParent());
String firstPart = originalFileLocation.getParent();
String modifiedFilePath = firstPart.replaceAll("src\\\\test\\\\resources\\\\","src\\\\test\\\\resources\\\\foo\\\\bar\\\\Unprocessed\\\\");
File unprocessedFile = new File(modifiedFilePath);
Path originalFileLocationPath = Paths.get(originalFileLocation.getPath());
unprocessedFile.delete();
Assert.assertFalse(!unprocessedFile.exists());
Path unprocessedFilePath = Paths.get(unprocessedFile.getPath());
File processedFile = new File("src\\\\test\\\\resources\\\\foo\\\\bar\\\\Processed\\\\test_file.csv");
Assert.assertFalse(processedFile.exists());
Files.copy(originalFileLocationPath, unprocessedFilePath, StandardCopyOption.REPLACE_EXISTING);
Assert.assertTrue(processedFile.exists());
int beforeProcess = repo.count();
Assert.assertNotNull(beforeProcess);
Assert.assertTrue(beforeProcess > 0);
File testFile = importService.processAndMoveFile(unprocessedFile);
int afterProcess = repo.count();
Assert.assertTrue(afterProcess > beforeProcess);
Assert.assertEquals(processedFile.getPath(), testFile.getPath());
processedFile.delete();
}
The most complex part with testing involving directories is that if your test unexpectedly fails or errors out, you will have a bunch of loose files that exist in your environment.
For sanity purposes, I would recommend using deleteOnExit();
as you create files and directories.
This feature allows you to mark files for deletion upon completed execution.
File file = new File("test.txt");
Assert.assertTrue(!file.exists());
file.createNewFile();
throw new Exception("Foo");
file.delete();
This test can be run once, after which it will constantly fail on assert.
File file = new File("test.txt");
file.deleteOnExit();
Assert.assertTrue(!file.exists());
file.createNewFile();
throw new Exception("Foo");
file.delete();
This test, with deleteOnExit, can be run repeatedly without failing on assert.
In the event that you are creating a directory, it follows FILO.
File foo = new File("foo");
foo.mkdir();
foo.deleteOnExit();
File bar = new File("foo/bar.txt");
bar.createNewFile();
bar.deleteOnExit();
This will delete bar first, then delete foo. Foo will not be deleted if bar is not deleted, so follow the teardown by declaring deleteOnExit as you create resources and children.