Reputation: 13698
In a Java application, I have a method of a class that saves a file just using its name.
public void doSomething(){
final File file = new File("XXX"+(new Random().next())+".txt");
file.createNewFile();
}
Then, in a unit test with JUnit 4, I run the class that execute the method and I see a file created with name XXX.txt
in the root folder of the project.
@Test
public void doSomethingTest() throws Exception{
//call doSomething();
Path path = //to project folder
Files.delete(path);
}
How can I get this path dynamically such that I can use a @After
method to delete it?
Upvotes: 0
Views: 10356
Reputation: 692231
The simplest way to do is to make your code testable by allowing it to inject the base directory where to create files.
Instead of
public Foo() {
}
public void doSomething() {
final File file = new File("XXX" + (new Random().next()) + ".txt");
file.createNewFile();
}
Use
private File baseDirectory;
public Foo() {
this(new File("."));
}
public Foo(File baseDirectory) {
this.baseDirectory = baseDirectory;
}
public void doSomething() {
final File file = new File(baseDirectory, "XXX" + (new Random().next()) + ".txt");
file.createNewFile();
}
Now your test can create a temporary empty directory, pass it to the constructor, call the method, check the files and delete them after the test.
This is probably a feature you would want anyway, because always writing in the current directory doesn't seem like a good idea to me.
Upvotes: 8
Reputation: 10853
I recommend, as was already suggested, to change the source code and pass the parent folder from outside, preferably in the class constructor.
If for some reason you cannot do it, then you can try to override the user.dir system property which controls the current working directory, that is where your files will be created by default.
Note that the user.dir
is global, so changing it will affect all the classes. For example, you won't be able to run your test concurrently.
Also in JUnit you can use the TemporaryFolder rule which would create a temporary directory before the test starts and delete it after the test finishes.
Example (copy-paste from the javadoc):
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");
// ...
}
}
Upvotes: 4
Reputation: 132
You can use Apache's commons-io. It has a FileUtils class that will do what you want.
Here is an example , implementation and its test `
import java.io.File;
import java.io.IOException;
public class FileSave {
public static void main(String[] args) throws IOException {
FileSave fileSave = new FileSave();
fileSave.saveFile("test.txt");
}
public void saveFile(String fileName) throws IOException {
final File file = new File(fileName);
file.createNewFile();
System.out.println("Hello");
}
}
`
Test file
`
import java.io.File;
import org.apache.commons.io.FileUtils;
import org.junit.Assert;
import org.junit.Test;
public class FileSaveTest {
@Test
public void checkFileSaved() throws Exception{
FileSave fileSave = new FileSave();
fileSave.saveFile("test.txt");
Assert.assertTrue(FileUtils.deleteQuietly(new File("test.txt")));
System.out.println();
}
}
`
the method FileUtils.deleteQuietly will return true when it delete , otherwise false.
Upvotes: 0
Reputation: 1658
You can use file.getAbsolutePath() to get the complete file path, expose it as a method and then delete it in the junit test.
Upvotes: 0