13

I have a class that does operations on file's on a disk. More exactly it traverses a directory, reads through all files with a given suffix and does some operations on the data and then outputs them to a new file.

I'm a bit dubious as to how to design a unittest for this class. I'm thinking having the setup method create a temporary directory and temporary files in /tmp/somefolder, but I'm suspecting this is a bad idea for a couple of reasons(Developers using windows, file permissions etc).

Another idea would be to mock the classes I'm using to write and read to the disk, by encapsulating the classes using an interface and then providing a mock object, but it seems to be a bit messy.

What would be the standard way of approaching such a problem?

Silfverstrom
  • 28,292
  • 6
  • 45
  • 57
  • Why would this be an issue on Windows any more than Linux? Windows has `%TEMP%` the same as Linux's `$TEMP`. Just don't hard-code `/tmp` and you're fine. – Matthew Scharley Sep 08 '11 at 08:48
  • Are you creating or just reading / traversing? You could include a sample directory of files in your source tree and just point your class at that directory to test. – Rup Sep 08 '11 at 08:54
  • Rup: I'm also creating files. Matthew Scharley: You're right of course, I didn't think of getting the path of the default tmpdir – Silfverstrom Sep 08 '11 at 09:06
  • 2
    @Sifverstrom: if you mock the read/write classes then you may not be unit testing what you want to test. I do such kind of "unit testing" (technically they may not be "unit" for things like JUnit are used for **much** more than "unit testing") with files/directories all the times. I reproduce entire hierarchies + fake files to process in temp directories and run the real code on these mock files. So I'd say in this case: mock the files, not the code. :) – SyntaxT3rr0r Sep 08 '11 at 10:57
  • See also http://stackoverflow.com/questions/3381801/how-do-i-unit-test-saving-file-to-the-disk – Raedwald Jul 05 '14 at 13:48
  • See also http://stackoverflow.com/questions/24566104/using-tdd-to-develop-file-traversing-code-in-java – Raedwald Jul 05 '14 at 13:52

3 Answers3

11

If using JUnit 4.7 and up, you can use the @TemporaryFolder rule to transparently obtain a temporary folder which should automatically get cleared after each test.

Alistair A. Israel
  • 6,417
  • 1
  • 31
  • 40
8

Your strategy is the right one, IMO. Just make sure not to hardcode the temp directory. Use System.getProperty("java.io.tmpdir") to get the path of the temp directory, and use a finally block in your test or a @After method to cleanup the created files and directories once your test is finished.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • Thanks, getting the tmpdir from System.getProperty seems like a good solution – Silfverstrom Sep 08 '11 at 09:07
  • 2
    If you are using Maven you could hardcode the path to the target folder and use that - as it gets cleaned during each `maven clean` – flob Sep 08 '11 at 12:05
7

Mocking everything out is possible, but probably much more effort than it's worth. You can use the temporary directory supplied from Java System.getProperty("java.io.tmpdir") which you should be able to write to etc. no matter which system you're on. Stick to short file names and you'll be safe even if running on something ancient.

CPJ
  • 1,635
  • 1
  • 9
  • 9