How to write junit test for DirectoryStream

1.4k views Asked by At

I have this function in a class called Test.java and it incudes;

public List<Path> getAllFoldersInTmp(String directory) throws IOException {
    final List<Path> files = new ArrayList<>();
    try (DirectoryStream<Path> stream = Files.newDirectoryStream(Path.of(directory))) {
        for (Path entry : stream) {
            if (Files.isDirectory(entry)) {
                files.add(entry);
            }
        }
    }
    return files;
}

so basically it returns all folders as a list in the "../../tmp" path. I want to write a test for it, and this is how i done but it does not work:

import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import org.junit.jupiter.api.Test;

class Testing{
    
    @Autowired
    Test test;
    @TempDir
    Path directory;
    
    @Test
    public void givenDir_whenUsingDirectoryStream_thenListAllFiles() throws IOException {
    
        File fileOne = directory.resolve("file1").toFile();
        File fileTwo = directory.resolve("file2").toFile();
    
        System.out.println(test.getAllFoldersInTmp("../../Temp")); //since the fileone and fileTwo are stored in `Temp/someRandomNumber` directory
    
    }
}

I am getting the following error;

 ..\..\Temp
java.nio.file.NoSuchFileException: ..\..\Temp
1

There are 1 answers

3
Oleksii Zghurskyi On BEST ANSWER

When using @TempDir you are free to not use some specific hard-coded paths (e.g. "../../Temp" in the snippent).

Basically, the temporary directory will be created for you automatically by junit. Then in the tests, you can manipulate it in the way you want, e.g. create files and directories.

If you need to get value of temporary directory path, you can simply invoke toString() on the field annotated with @TempDir.

For example, for your specific case following test can be written:

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;

class FoldersResolverTest {

    @TempDir
    Path directory;

    // assume FoldersResolver wrapps getAllFoldersInTmp 
    FoldersResolver foldersResolver = new FoldersResolver();

    @Test
    void directoriesAreFoundAndFilesAreSkipped() throws IOException {

        Path fileOne = directory.resolve("file1");
        Path fileTwo = directory.resolve("file2");
        Path directoryOne = directory.resolve("directory1");
        Path directoryTwo = directory.resolve("directory2");

        Files.createFile(fileOne);
        Files.createFile(fileTwo);
        Files.createDirectory(directoryOne);
        Files.createDirectory(directoryTwo);

        // note directory.toString() returns path to the temporary folder created by junit
        List<Path> actual = foldersResolver.getAllFoldersInTmp(directory.toString());

        List<Path> expected = List.of(directoryOne.getFileName(), directoryTwo.getFileName());
        assertEquals(expected, actual);
    }
}

Note: In general, @TempDir makes use of the default system temporary file directory. This depends on operating system, and normally can be found via environment variable. For example, TMPDIR on my system points to /tmp directory.