Stylishcoder
Stylishcoder

Reputation: 1212

Unit Testing code that creates directories

I have code that creates directories and transfer files to it. I want to unit test it. But the problem is when i run the unit test these directories are created but i don't want that. I want the code to create these directories only when its running a production environment. I have googled about this, but all search results suggest the JUnit class TemporaryFolder. But that is not what i want. I am not creating directories inside my test cases. I am just testing code that creates them. So am not sure how TemporaryFolder class can help me with that. say i have code like below

public class Util {

    public File getLocation(String location) {
        File result = new File(location);

        if (!result.exists()) {
            result.mkdirs(); 
        }
        return result;
    }
}

How do I unit test such code? Every time I call

util.getLocation("base/location"); 

the directories base/location are being created but I don't want that. They should only be created when I run the code in production environment.

UPDATE Due to the comments on the question. I've decided to update my question. First the getLocation signature is a little misleading. That is not the exact code that i am testing, its kind of long and so i tried to convey the idea with that. It functions basically the same but the problem is that getLocation() takes no parameter as shown above. Inside getLocation another method is called which returns a string to a path. Which means i have no control over what is been used in creating the directories. And also i run both production and development environment and once these directories have been created while running production code, they should not be deleted even if the code is rebuilt because the unit test will be run on every build.

public File getLocationForReports() {

    String softwareHome = GeneralUtil.getSoftwareHome();
    File path = new Path(softwareHome, "reports").toFile();

    if (!path.exists()) {
        path.mkdirs();    
    }
    return path;
}

As you can see above i don't have control of what GeneralUtil.getSoftwareHome() returns so i cannot even send in a dummy location like "tmp/location" and delete later and i also don't want to delete these directories if they were created when the production code is run because I'll some files.

Upvotes: 3

Views: 3583

Answers (2)

GhostCat
GhostCat

Reputation: 140427

I suggest to do whatever you can to not use PowerMock to do any testing.

PowerMock manipulates your production classes; it often leads to really bizarre errors (that you can hunt down for hours, without ever finding a real problem in your code); and it kills your ability to do coverage.

In other words: for me, the "need" for PowerMock very much translates to: your design isn't structured to allow for reasonable testing. And instead of investing into the big ugly PowerMock hammer ... you better spent time reworking your design!

In your case: get rid of calls to static methods; make sure that you can use dependency injection in order to provide mocked objects to your code. Meaning: frameworks like EasyMock allow you to create mocked objects that do whatever you want them to do. You pass such "prepared" mocks to your code under test; and then you have completely control over what will be going during your tests.

You see, in essence your problem is that your production code is doing too many things in one place; therefore you have such a hard time testing it. Rip it apart, put each "responsibility" found in that code into separate classes/methods; and test those individually.

Upvotes: 6

Flying Dutch Boy
Flying Dutch Boy

Reputation: 354

I suggest using PowerMock to create your tests. There are 2 ways to do this. Both will need PowerMock and the tests will be needed to be annotated like this: @RunWith(PowerMockRunner.class) @PrepareForTest(Class that you want to test.class)

First you can try to Mock out the static call to GeneralUtil.getSoftwareHome() using powermockito. PowerMockito mock single static method and return object

The second option is to mock out the constructor for the Path object and the calls it returns: mockito mock a constructor with parameter

This way you can test the functionality of your code.

Upvotes: 0

Related Questions