Singletons and testing

When you need to jump through hoops to write tests you’ve done it wrong. Jonathan de Halleux writes about testing singletons and how he can subvert the standard C# singleton pattern to create a new singleton for each test he needs to run for the singleton. Omer then subverts the rules another way. Both are wrong.

Firstly Singletons are evil. Really. It’s a useful pattern but it’s way over used as some covert global variable. There really aren’t that many cases where you really need a singleton and in all of those cases you NEVER need to allow the world to access your singleton via a static ‘give me the instance’ method that’s called from everywhere. If you think you do then you need to work on your design some more, it’s broken, you’re wrong, you can just pass the object in to whoever needs it.

If you DO use the ‘classic’ singleton pattern and allow all and sundry to reach out and grab hold of your singleton object then you’ve just created a global variable and you’ve just coupled all of the code that uses it to a single implementation. This is bad news, both from a testing point of view and a code structure point of view. You’re hiding the complexity, and, as you know, I don’t like hidden complexity, I like it all to be explicit.

Half of the classic singleton is a useful concept; a class that has only one instance. The other half is bollocks; providing a global way to access that single instance.

The problem with both of these ‘ways to cheat’ when testing singletons is that they’re solving the wrong problem. The problem that needs to be solved is testing the class that can only have one instance. Unfortunately the designers of that class were short-sighted and decided that there could only ever be one instance… Since the ‘cheats’ work, this is obviously not true. If the tests pass then it must be legit and safe to create and destroy multiple instances of the class. This means the singleton nature is secondary to the real work of the class in question. In this situation the class itself could be split in two. The class that does all the work and the singleton aspect that prevents multiple instances. If you do this then you can test the class and all aspects of the class without worrying about the singleton stuff. The singleton stuff would likely be a template; ok they’re in C# so they don’t have that amount of power in their tool, but the singleton part could still be separate… Orthogonal services; write the real code without worrying about the singleton state…

In the very, very, really very very, rare situations where you might need to access some global thing from everywhere in your program, and I’m thinking logging here, and I still don’t buy it… The singleton in question should, IMHO, be a pluggable factory, and that fits fine with what I’ve said above. Write the object that you need to use as a singleton, test it and then supply it to a class that provides the singleton nature you require. If you do that then you can a) test the singleton class without ‘clever’ tricks and b) test classes that use the singleton with a mock that allows you to replace the functionality with something appropriate for testing.

Singletons, just say no.