Unit testing singletons

I wrote a post about that here: http://pvlerick.github.io/2017/03/how-to-get-rid-of-a-singleton

TL;DR:

  1. Extract an interface from the Singleton (even if you don't own it) and make your class work against that interface instead of the Singleton's instance;
  2. Depending on whether you own the Singleton or not, you can make it implement that interface or you'll need a simple adapter.

When attempting to test the singleton itself the following could be a possible solution:

public class Singleton
{
    private static Singleton _Instance;

    public static Singleton getInstance() {
        if (_Instance == null)
        {
            _Instance = new Singleton();
        }

        return _Instance;
    }

    private Singleton()
    {
    }

    public static resetForTesting() {
        _Instance = null
    }
}

So, in your unit testing framework you would call Singleton.resetForTesting() before each unit test.

Note: the downside of this approach is that there is no code level restriction that would stop somebody from invoking this method within production code even though it is only meant to be used with testing code. So, you would have to rely on documentation to convey that to other people.


Short version: do not write your singletons as singletons. Write them as normal classes, and call them via an Inversion of Control container, where you have configured the class to be a singleton instead.

That way, you can unit-test the class just fine and if you decide today or tomorrow that singleton is not the right lifestyle for the class, simply modify the configuration of the IoC container.