CuriousCoder
CuriousCoder

Reputation: 1600

Unit test existence of a directory - Junit

I have a function that I use to detect whether a certain directory path exists. Here's the function:

public boolean isRunningOnSandbox() {
   return Files.isDirectory(Paths.get("/mySandbox/cloud/sandbox"));
}

As you can see, it relies on static method isDirectory. In my team, we do not use PowerMock for testing.

So, how can I test this method? I have tried writing a test like:

@Rule
public TemporaryFolder temporaryFolder;

@Test
public void test() throws IOException {
    File parent = new File("/");
    temporaryFolder = new TemporaryFolder(parent);
    temporaryFolder.create();
    File folder = temporaryFolder.newFolder("mySandbox", "cloud", "sandbox");
    subject.isRunningOnSandbox();
}

But, I get an error

ava.io.IOException: Permission denied

because it doesn't let me create a temporary folder under the root. I am guessing there is a better way to test this code instead of trying to create a folder.

Upvotes: 4

Views: 2818

Answers (2)

Dirk Herrmann
Dirk Herrmann

Reputation: 5939

The function you have shown is not suited for unit-testing: With unit-testing you try to find the bugs in small, isolated software pieces. But, which bugs could be in this example code that are not related to the other components, that is, the Files component, the Paths component and the actual file system?

The potential bugs in your example are about questions like "am I calling the right functions?" or "do I call the functions with proper values for the arguments?" or "do the functions I call return arguments as I expect" or "am I using the path that is also the path found in the file system". This can not be checked with unit-testing, but with integraton-testing.

Imagine you have the wrong path in mind. Then, in your unit-test you would also check against the same wrong path, and your unit-test would succeed. Only when running that test as an integration test on the real file system you could figure out that the path which you had in mind was wrong and did not match the actual path in the file system.

Upvotes: 0

krokodilko
krokodilko

Reputation: 36107

There are many ways to do it, onee of them migh be like the below one.
Assumming that isRunningOnSandbox method is in some class SomeClass, then refactor this class in this way:

public class SomeClass {

    public boolean isRunningOnSandbox() {
        return Files.isDirectory(Paths.get(getSanboxPath()));
    }

    protected String getSanboxPath(){
        return "/mySandbox/cloud/sandbox";
    }
}

and then in your tests inject into this class another directory to which you have access, for example:

public class SomeClassTest {

    class SomeClassToTest extends SomeClass{
        String folder;
        public SomeClassToTest(String folder){
            this.folder = folder;
        }
        @Override
        protected String getSanboxPath(){
            return folder;
        }
    }

    static String sandboxFolder = "myTestSandobxFolder";

    static Path tempDir;

    @BeforeClass
    public static void createFolder() throws IOException {
        tempDir = Files.createTempDirectory(sandboxFolder);
    }

    @AfterClass
    public static void deleteFolder() throws IOException {
        Files.delete(tempDir);
    }

    @Test
    public void IsRunningOnSandbox_shouldReturnTrueWhenPathExists() throws IOException {
        //given
        SomeClass testedObject = new SomeClassToTest(tempDir.toString());
       //when
        boolean result = testedObject.isRunningOnSandbox();
        //then
        assertThat(result).isTrue();
    }

    @Test
    public void IsRunningOnSandbox_shouldReturnFalseWhenPathDoesNotExist() throws IOException {
        //given
        SomeClass testedObject = new SomeClassToTest("/abcdef123");
        //when
        boolean result = testedObject.isRunningOnSandbox();
        //then
        assertThat(result).isFalse();
    }
}

Upvotes: 1

Related Questions