Reputation: 1600
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
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
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