Mocking a dependency is possible and natural, but mocking an object declared in the body of the method is not natural and tricky.
I imagine 3 solutions:
1) Why, instead of mocking, could you not simply assert that the file is written with the expected character?
It avoids tricks, but it may be redundant and slow if you perform this task very often and you want to unit test them.
2) Making the local variable an instance field to mock it. This seems really a not at all clean solution. If you have multiple methods in the same class that does this kind of processing, you risk to reuse the same writer or to have multiple writer fields. In both cases, you could have side effects.
3) If you perform many write operations and you want to really isolate the call to the writer, you have a solution: redesign your code to have a testable class.
You could extract a dependency to perform the writer processings. The class could provide a method with required parameters to perform instructions. We could call it : WriteService
.
public class WriteService {
...
public void writeAndClose(Writer writer, String message){
try {
writer.write(message);
writer.close();
}
catch (IOException e) {
throw new IndexFileInitializationException("Error initialization index file " + emptyIndexFile.getPath());
}
}
}
This class is testable because the writer dependency is a parameter.
And you call the new service like that :
public class YourAppClass{
private WriteService writeService;
public YourAppClass(WriteService writeService){
this.writeService=writeService;
}
@Override
public void initIndexFile(File emptyIndexFile) {
Writer writer = new FileWriter(emptyIndexFile);
writeService.writeAndClose(writer,"[]");
}
}
Now initIndexFile()
is also testable by mocking WriteService
.
You could check tat writeAndClose() is called on writeService with the good parameter.
Personally, I would use the first solution or the third solution.