In my previous Singleton Unit Testing, I proposed a possible solution for unit testing a singleton (I'll name it the ShortLivingSingleton approach). Omer Van Kloeten came up with another approach (the KillTheSingleton approach), Darren Oakey with the CreateForTesting approach and , Len Holgate finishes the picture tearing appart our the first 2 solutions (the SingletonIsBad approach). Since comments on this topic have been interresting, they are worth a little summary.
The problem
The application you are developping is using a Singleton, that you need to test. How do you test a singleton ?
SingletonIsBad approach
The two first point came from Len Holgate and I totally agree with him. The third point is for tester who do not have the possiblity of avoiding or refactoring the singleton. To tackle this problem, I and Omer have proposed 2 cheats and Darrel Oakley proposed a wider solution to the problem.
CreateForTesting approach
The approach asks you to embed some functionality in a class that helps other people test it. The most common thing is to add - to most objects - a function CreateTestFoo, where Foo is the object that you are testing. This gives you a new and fully initialized version of Foo - however complicated Fooactually is.
Cheating the singleton.
Both cheat solutions are based on Reflection, therefore they will not work if you have denied Reflection on your tested assembly (Haacked's comment).
ShortLivingSingleton approach
This approach consists of creating a new non-singleton approach for each test and do the testing on this instance. To do so, we use reflection to access the private constructor and instanciate the singleton. Therefore, the singleton is never created and never used.
KillTheSingleton approach
This approach kills the singleton after each test, in the TearDown method for example. To "kill" the singleton, the static field holding the singleton reference is nullified using Reflection and garbage collection is forced.
Conclusions
Singletons are evil but yet you find people using them (shame on me). They are problematic to test because you cannot separate the unit tests. The first step for testing them is actually to refactor your application and get rid of the singleton. If this cannot be done, you have to cheat the singleton using Reflection to properly test them.
ps: I'd like to thank all the people who commented the blog entry for their constructive comments :) Cheers, Jonathan
Page rendered at Friday, November 21, 2008 3:29:48 PM UTC
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.