Deleting File and Directory in JUnit

2020-06-04 13:12发布

问题:

I'm writing a test for a method that creates a file in a directory. Here's what my JUnit test looks like:

  @Before
  public void setUp(){
      objectUnderTest = new ClassUnderTest();
      //assign another directory path for testing using powermock
      WhiteBox.setInternalState(objectUnderTest, "dirPathField", mockDirPathObject);

      nameOfFile = "name.txt";
      textToWrite = "some text";
  }

  @Test
  public void shouldCreateAFile(){


      //create file and write test
      objectUnderTest.createFile(nameOfFile, textToWrite);
      /* this method creates the file in mockPathObject and performs
         FileWriter.write(text);
         FileWriter.close();
      */

      File expect = new File(mockPathObject + "\\" + nameOfFile);
      assertTrue(expect.exist());

      //assert if text is in the file -> it will not be called if first assert fails
  }

  @After
  public void tearDown(){
       File destroyFile = new File(mockPathObject + "\\" + nameOfFile);
       File destroyDir = new File(mockPathObject);

       //here's my problem
       destroyFile.delete(); //why is this returning false?
       destroyDir.delete(); //will also return false since file was not deleted above

  }

I was able to delete the File using deleteOnExit() but I will not be able to delete the directory using delete or deleteOnExit. I will also perform other test for other scenarios in this test script so I don't want to use deleteOnExit.

I don't know why I cannot delete it in JUnit test script while I can delete a file created and modified by FileWriter in runtime when the code is not a JUnit test. I also tried performing an infiniteLoop after the test method and delete the file manually but it tells me that other program is still using the file though I'm able to modify its content.

Hope somebody can suggest a way to delete the files and directories created during the tests. Thanks :D

For more clarity, the method I test looks like this Unit testing method that invokes FileWriter

Edit:Here is the method to test

    public void createFile(String fileName, String text){

           //SOME_PATH is a static string which is a field of the class
           File dir = new File(SOME_PATH); //I modified SOME_PATH using whitebox for testing

           if(!dir.exists()){
                booelan createDir = dir.mkdirs();
                if(!createDir){
                           sysout("cannot make dir");
                           return;
                }
           }


           try{
                 FileWriter fileWrite = new FileWriter(dir.getAbsolutePath() + "/" + fileName, true);
                 fileWrite.write(text);
                 fileWrite.close();
           }
           catch(Exception e){
                 e.printStackTrace();
           }

    }

I cannot modify this method as other developers created it. I was just instructed to create unit tests for test automation. Thanks.

回答1:

Use the @Rule annotation and the TemporaryFolder classfor the folder that you need to delete.

http://kentbeck.github.com/junit/javadoc/4.10/org/junit/Rule.html (404 not found)

Update example of usage by http://junit.org/junit4/javadoc/4.12/org/junit/rules/TemporaryFolder.html:

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");
    // ...
  }

}


回答2:

This is how I usually clean up files:

@AfterClass
public static void clean() {
    File dir = new File(DIR_PATH);
    for (File file:dir.listFiles()) {
        file.delete();
    }
    dir.delete();
}

Your directory must be empty in order to delete it, make sure no other test methods are creating more files there.

Ensure you are closing the FileWriter instance in a finally block.



回答3:

Ensure that the method objectUnderTest.createFile(nameOfFile, textToWrite) actually closes any opened streams?



回答4:

I think the best approche is te delete after JVM exit :

Path tmp = Files.createTempDirectory(null);
tmp.toFile().deleteOnExit();