Testing: jUnit's TemporaryFolder

Testing: jUnit's TemporaryFolder

with Simple CSV generator

The problem

Lately I had a question in my head: how to test a method, which output is a file? 
Should I divide creation of file from creation of content and test only the latter part?

Well, usually I would like to call a method "generateReport" or retrieveFileByHash(), which encapsulate all file-connected operations and return simple java.io.File. In other words, my service classes looks like this:
  • Interface (like ReportGenerator)
    • one method
    • returns: File
  • Concrete class (like DefaultReportGenerator)
    • one public implementation of interface method, (like generateReport())
      • returns: File
    • set of private methods
      • returns: whatever is needed to create File
With such services, file's content creation is separated from File creation:
  • Interface - ReportGenerator
    • method: generateReport()
    • returns File
  • Concrete Class - DefaultReportGenerator
    • method: implementation of generateReport()
      • public
      • return File
    • method: retriveSystemDataFromCurrentMonth()
      • private
      • returns List of data for report
But since retrieving data is isolated in private method, I cannot simply test it - I would have to call public method anyway and create file, then save it somewhere, confirm its content is valid and proper and then remove it at the end of a test.

The solution

To test such a behaviour, I had to create proper intergration test, since unit tests should not touch file system, according to Michael Feather's. And then, use special thing in jUnit 4 - @Rule TemporaryFolder. It handles all file's operations and guarantees to delete files created through the test.

So to play with this functionality, I created very basic CSV file generator. It works on any entity implementing special proper interface. Let's check integration test.


@Rule
public TemporaryFolder testFolder = new TemporaryFolder();
private String filePath;
private final String FILENAME = "testCsvFile.csv";
@Test
public void generate___shouldSucceed() throws IOException {
// given
filePath = this.generateFilePath();
SystemUser systemUser = new SystemUser(NAME, EMAIL);
CsvFileGenerator csvFileGenerator = new SimpleCsvFileGenerator(
filePath);
// when
File file = csvFileGenerator.generate(List.of(systemUser));
// then
assertTrue(file.exists());
assertTrue(file.isFile());
assertEquals(FILENAME, file.getName());
List<String> content = Files.lines(Paths.get(file.getAbsolutePath()))
.collect(Collectors.toList());
assertEquals(2, content.size());
assertEquals("Identificator,User's name,User's email", content.get(0));
assertEquals("1,Test name,Test email", content.get(1));
}
I create CSV file inside the TemporaryFolder and I do not have to care about any other thing :)

Full sample project: https://github.com/toficzak/SimpleCsvGenerator

In the following posts I will try to implement proper abstraction in CSV generator, allowing it to create file's in production environment and mock it in test environment.

Some resources:


Komentarze

Popularne posty z tego bloga

Java EE 8 & Wildfly 17 & RestEasy setup

Optional finallyLearned()