Ula Krukar
Ula Krukar

Reputation: 12999

Unit test with files system dependency - hidden files

I am writing a "Total Commander" like application in Java. There is quite obvious file system dependency here.

I want to unit test it. I created directory structure for test purposes, I keep it in known location in SVN repository. It works great so far.

Now, I have a method that should ignore hidden files. How can I go about this? Can I mark file hidden in the SVN somehow?

Other solution would be to make one of the files hidden in the build script before running tests, but I'm afraid this would mark file as modified and always show in a commit dialog.

Any suggestions?

Upvotes: 4

Views: 1519

Answers (4)

Assaf Stone
Assaf Stone

Reputation: 6317

Essentially, accessing the file system is a big no-no when unit testing. For starters, these tests are slow(er) than your in-system tests, thus reducing the likelihood of you running your tests at a high frequency (such as with every compilation).

Much better if you use an adapter-pattern to abstract away the access to the file system. I'm a .NET developer so my example will be in C#, but I expect you to be able to translate it simply enough:

public class MyManager
{
    private readonly IFileAdapter _fileAdapter;
    public MyManager(IFileAdapter fileAdapter)
    {
        _fileAdapter = fileAdapter;
    }
}

public interface IFileAdapter
{
    public FileStream Open(string fileName);
    public string ReadLine(FileStream fileStream);
    // More methods...
}

public class FileAdapter : IFileAdapter
{
    public FileStream Open(string fileName)
    {
        return System.Io.File.Open(fileName);
    }

    public string ReadLine(FileStream fileStream)
    {
        return File.Open(fileStream);
    }
}

Now, as usual, you can mock the file system, as you would any other class, supplying the returned results. Remember - you are not testing Java's IO classes it is assumed that they work. You are only testing your classes (i.e. MyManager, in the example above).

Leave the tests that actually use the file system to your integration / acceptance tests.

Hope this helps, Assaf.

Upvotes: 3

pgras
pgras

Reputation: 12780

artemb's answer is correct, you can use @Before and @After to create and remove your structure for each test.

Here is some code I use to create a new directory with some files in it, it will create the directory in the systems temp dir, this is important because depending on the machine your tests will run on, you may will not be allowed to create files or dirs somewhere else. (I had to write this code to allow my tests to be executed on our linux integration machine...)

    final String tempdir = System.getProperty("java.io.tmpdir");
    final String dirname = Long.toHexString(System.currentTimeMillis());
    final File dir = new File(tempdir, dirname);
    dir.deleteOnExit();
    dir.mkdir();
    final String path = dir.getAbsolutePath();
    assertTrue(dir.exists());
    // pre condition, the directory is empty
    assertTrue(dir.list().length == 0);

    // create temp files in the directory
    final int nbFiles = 3;
    for (int i = 0; i < nbFiles; i++) {
        (File.createTempFile("test", ".txt", dir)).deleteOnExit();
    }

BTW you will have to know on what platform you run to be able to create hiden files...

Upvotes: 0

Rorick
Rorick

Reputation: 8953

I would prefer to abstract file system, so that my unit-test wouldn't require access to real file system. Of course, this abstraction layer must be tested with real file system, but this allow you to reduce dependency on it.

As for storing hidden files in SVN, I second artemb. You should create all files necessary to test in JUnit set up. Presumably, you should prefer setup per test method (@Before and @After). But if you encounter test slowness problems, have a look at @BeforeClass and @AfterClass. I consider they can be used with test suites too.

Upvotes: 2

artemb
artemb

Reputation: 9381

I would put all the initialization of a test directory into the tests themselves. And such a case would be simple:

  • create a directory
  • put some hidden and visible files into it
  • test
  • tear down by removing the directory

Upvotes: 10

Related Questions