package org.junit.rules; import java.io.File; import java.io.IOException; import org.junit.Rule; /** * The TemporaryFolder Rule allows creation of files and folders that should * be deleted when the test method finishes (whether it passes or * fails). Whether the deletion is successful or not is not checked by this rule. * No exception will be thrown in case the deletion fails. * * <p>Example of usage: * <pre> * public static class HasTempFolder { * @Rule * public TemporaryFolder folder= new TemporaryFolder(); * * @Test * public void testUsingTempFolder() throws IOException { * File createdFile= folder.newFile("myfile.txt"); * File createdFolder= folder.newFolder("subfolder"); * // ... * } * } * </pre> * * @since 4.7 */ public class TemporaryFolder extends ExternalResource { private final File parentFolder; private File folder; public TemporaryFolder() { this(null); } public TemporaryFolder(File parentFolder) { this.parentFolder = parentFolder; } @Override protected void before() throws Throwable { create(); } @Override protected void after() { delete(); } // testing purposes only /** * for testing purposes only. Do not use. */ public void create() throws IOException { folder = createTemporaryFolderIn(parentFolder); } /** * Returns a new fresh file with the given name under the temporary folder. */ public File newFile(String fileName) throws IOException { File file = new File(getRoot(), fileName); if (!file.createNewFile()) { throw new IOException( "a file with the name \'" + fileName + "\' already exists in the test folder"); } return file; } /** * Returns a new fresh file with a random name under the temporary folder. */ public File newFile() throws IOException { return File.createTempFile("junit", null, getRoot()); } /** * Returns a new fresh folder with the given name under the temporary * folder. */ public File newFolder(String folder) throws IOException { return newFolder(new String[]{folder}); } /** * Returns a new fresh folder with the given name(s) under the temporary * folder. */ public File newFolder(String... folderNames) throws IOException { File file = getRoot(); for (int i = 0; i < folderNames.length; i++) { String folderName = folderNames[i]; validateFolderName(folderName); file = new File(file, folderName); if (!file.mkdir() && isLastElementInArray(i, folderNames)) { throw new IOException( "a folder with the name \'" + folderName + "\' already exists"); } } return file; } /** * Validates if multiple path components were used while creating a folder. * * @param folderName * Name of the folder being created */ private void validateFolderName(String folderName) throws IOException { File tempFile = new File(folderName); if (tempFile.getParent() != null) { String errorMsg = "Folder name cannot consist of multiple path components separated by a file separator." + " Please use newFolder('MyParentFolder','MyFolder') to create hierarchies of folders"; throw new IOException(errorMsg); } } private boolean isLastElementInArray(int index, String[] array) { return index == array.length - 1; } /** * Returns a new fresh folder with a random name under the temporary folder. */ public File newFolder() throws IOException { return createTemporaryFolderIn(getRoot()); } private File createTemporaryFolderIn(File parentFolder) throws IOException { File createdFolder = File.createTempFile("junit", "", parentFolder); createdFolder.delete(); createdFolder.mkdir(); return createdFolder; } /** * @return the location of this temporary folder. */ public File getRoot() { if (folder == null) { throw new IllegalStateException( "the temporary folder has not yet been created"); } return folder; } /** * Delete all files and folders under the temporary folder. Usually not * called directly, since it is automatically applied by the {@link Rule} */ public void delete() { if (folder != null) { recursiveDelete(folder); } } private void recursiveDelete(File file) { File[] files = file.listFiles(); if (files != null) { for (File each : files) { recursiveDelete(each); } } file.delete(); } }