First things first: why reinvent the wheel instead of using Files.writeString?
Assuming you are looking for a more general solution to test code that touches the file system: I'd try to keep any external resource (network, database, other processes, file system) out of my unit tests. You'll end up with brittle tests that depend on e.g., file system details (latency, cleanup between tests, tests running in parallel may step on each others toes).
Then: please use try with resources:
private void writeFileOut(String fileContents, String fileName) throws IOException {
File fullFilePath = new File("/temp/directory/" + fileName);
try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(fullFilePath))) {
bufferedWriter.append(fileContents);
}
catch (IOException e) {
LOGGER.info("Error writing file out: " + e.getMessage());
throw e;
}
}
Now your code does 3 things:
- create the path for the file
- write the given data to the file
- log if an error occurs
It's often easiest to move code you want to test into new methods that you can call separately, instead of having to test through all the other code. So isolate pieces of code, especially the code that tries to use the file system.
private void writeFileOut(String fileContents, String fileName) throws IOException {
File fullFilePath = new File(makeTempPath(fileName));
try (Writer bufferedWriter = makeWriter(fullFilePath)) {
bufferedWriter.append(fileContents);
}
catch (IOException e) {
LOGGER.info("Error writing file out: " + e.getMessage());
throw e;
}
}
String makeTempPath(String fileName) {
return "/temp/directory/" + fileName;
}
Writer makeWriter(String fullFilePath) {
return new BufferedWriter(new FileWriter(fullFilePath));
}
Now you can test makeTempPath
separately.
You can mock makeWriter
when you test writeFileOut
. You can check that it receives what it was supposed to receive. You can have it throw to trigger the error handling.
When you mock, you can use a framework like Mockito or you create a derived class for the methods you want to mock and override them. Note that makeWriter
returns a Writer
. In real life this is the BufferedWriter
that writes to a file. In testing you can return a StringWriter to capture what gets written.
Either way, be careful not to mock too much, or you may end up just testing your mocks, not the production code.