We’ve all been at a point where in we’re writing up test cases for our application and we encounter a static method from the
java standard library being called. Everything goes downhill from there. Mockito would give you ambiguous error messages. Notice there is no reason shared as to why is it throwing a
NullPointerException and this is at the time of mocking.
This post does expect some familiarity with
Unit testing using frameworks like
Mockito . The code sample is in
Java 8 and does require one to have an understanding about
Functional Interfaces and
Lambda functions in general. But it’s not something you would need in depth understanding of. If you’re not from a Java background, don’t worry the code is fairly straight forward and readable, so you would be able to follow along.
What about other frameworks?
That’s a fair question. What about
PowerMock? While I was researching on the topic I came across the PowerMock git repo, which explicitly states:
Writing unit tests can be hard and sometimes good design has to be sacrificed for the sole purpose of testability.
It helps unit test these methods but I could never make my peace with using a whole framework for just a few usages here and there. If you’d rather use a framework instead, then there are a lot of frameworks and the most popular one is PowerMock.
For the simplicity of the blog post, let’s assume you’re writing a method that gets a
rootDirectory and a
fileName. The method needs to return the contents of the file. Now if using
Java you would use the
java.nio.file.Files API to call a method called
walk() to iterate through all files in the directory and then you would use the
readAllBytes() method in the
java.nio.file.Files to read the contents of the file. The overall code would look like
The problem is, the
java.nio.file.Files.walk() method and
java.nio.file.Files.readAllBytes() method are both
static. This causes a problem in unit testing this code since, we would not be able to
mock the responses of these methods.
Functional Interfaces to the rescue
What we can notice, is that we are using two methods
readAllBytes() and we don’t quite need any other method which is a part of
The intuition is to create two functional interfaces,
FileReader (reads all files in a directory) and
ContentReader (reads the content of a single file) each doing one part of the process. Now instead of using
java.nio.file.Files class, we inject the two
Functional Interfaces using
Below is the updated code.
Now you can simply use
Mockito to mock the dependencies using the
@Mock and then use
Mockito fluent syntax to mock the behaviour.
Why Functional Interfaces and not a Util class?
The answer is code coverage. Considering you create a new class and wrap the
Files class methods, you still would have to deal with code coverage issues. Although, to test out your
FileOperator class, you can mock dependency, you still have
zero coverage on your Util class. Is that a good practice or not? is opinion based.
Also, using functional interfaces make it easier to inject dependencies especially when using a
Dependency Injection framework like
In this blog post we looked at how to make the code that uses java standard library static methods, more testable.
I do not recommend you make Functional Interfaces for all your static methods because you can always refactor your code to make it more unit testable but when it comes to the java standard library, things become out of our hands.
Like this article? Please consider following @iam_Carrot on Twitter. Maybe click the clap👏 button a few times to show your support ⬇⬇