I came across this problem when I was writing code for my
product. We follow Test Driven Development as it suites our process. Well there
are lots of benefits that you can get from Test Driven Development; I won’t dig
deeper into that. But I faced lots of problems trying to adhere to this coding
practice.
I had implemented this new interface and a private class that
implements this interface. This new class was singleton. Now the
methods in this interface are used across many classes in many projects in the production
code, all these classes are Unit tested. Since they unit tested, changing the
code in these classes make things messier. But I had to take the pain of
modifying the production code as well as the Unit test projects. But the tests
still kept failing.
All I was trying to do is create a new interface pointer,
and then use it across the class. I created this new interface pointer in the
constructor of the classes that use this singleton class.
In the test class I was creating the interface pointer in
the setup method of the class that use the singleton, but all the test cases were
failing when I tried to call the interface’s methods in the test cases. The failed
reason was null pointer. Now I couldn’t understand the reason for being null as
the interface pointer is created in the setup method and setup method is
definitely called every time.
One fine day I found out the actual root cause, the manner
in which the interface pointer was getting created and passed was wrong. Since
the new class was singleton, the object creation took place only when the
production code was run, generally when you run the test cases the production code
won’t get executed, hence the interface pointer was turning out to be null.
The solution for this is Dependency Injection. Since the test classes depended on the classes
that used the new class and interface pointer was getting created in the
constructor, I had to pass this pointer to the test cases. For the test cases
to pass, I had to write a separate constructor with an extra parameter i.e.
interface pointer. I am INJECTING the interface pointer so that the test cases ‘that
DEPEND on it won’t fail.
So now in the test class, in the setup method, every time I created
the production class’s object, I passed the interface’s pointer. After taking
the pain of changing the code (again!), I finally managed to make the test
cases pass.