Working With Temporary Files in JUnit 4.7

Another handy feature in JUnit 4.7 is the TemporaryFolder @Rule. Using this rule, JUnit will create a temporary folder before your test, and delete it afterwards, whether the test passes or fails. This comes in very handy for tests involving file manipulation of any sort.

Of course you can write this code yourself (and most of us have!), but any infrastructure coding in tests is tiresome at best, and at worst will discourage developers (present company excluded, of course ;-)) from doing the sort of thorough testing that any file-based functionality really requires. So any build-in help in this area is very welcome.

The TemporaryFolder @Rule is easy to use: you just create a TemporaryFolder variable using the @Rule annotation as shown below, and then use this variable to create your files and directories in your tests. In the example shown below, we are testing the DynamicMessageBundle class, an imaginary class that extends a standard Properties file with features such as being able to be reloaded dynamically or from different data sources. In the test shown here, we are testing that we can load the file from a standard properties file. In a @Before method, we create a properties file in the temporary folder created by JUnit. We then use this file for our tests. It will be destroyed, along with the temporary folder, after the test has finished.

public class DynamicMessageBundleTest {

@Rule
public TemporaryFolder folder = new TemporaryFolder();

private File properties;

@Before
public void createTestData() throws IOException {
properties = folder.newFile("messages.properties");
BufferedWriter out = new BufferedWriter(new FileWriter(properties));
out.write("first.name = Arthur\n");
out.write("last.name = Dent\n");
out.write("favorite.object = Towel\n");
out.close();
}

@Test
public void shouldLoadFromPropertiesFile() throws IOException {
assertThat(properties.exists(), is(true));

DynamicMessageBundle bundle = new DynamicMessageBundle();
bundle.load(properties);
assertThat(bundle.getProperty("first.name"), is("Arthur"));
assertThat(bundle.getProperty("last.name"), is("Dent"));
assertThat(bundle.getProperty("favorite.object"), is("Towel"));
}

@After
public void cleanUp() {
assertThat(properties.exists(), is(true));
}
}

The TemporaryFolder is not a File object as such: you use methods such as newFile() and newFolder() to create temporary files and directories. It does however conceptually represent a real temporary directory that JUnit has created for you - you can get hold of this temporary directory using the getRoot() method. The temporary directory will be created just before each test is run, and it will be deleted (along with any files it contains) just after the test, and also after any @After methods (as illustrated in the @After method shown above).

John is a freelance consultant specialising in Enterprise Java, Web Development, and Open Source technologies, currently based in Wellington, New Zealand. Well known in the Java community for his many published articles, John helps organisations to optimize their Java development processes and infrastructures and provides training and mentoring in open source technologies, SDLC tools, and agile development processes. John is principal consultant at Wakaleo Consulting, and runs several Training Courses on open source Java development tools and best practices. John is a DZone MVB and is not an employee of DZone and has posted 58 posts at DZone. You can read more from them at their website.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)