The Effective Java has the following statement on unit testing singletons
Making a class a singleton can make it difficult to test its clients, as it’s im
It's oh so simple.
In unit-testing, you want to isolate your SUT (the class you're testing). You don't want to test a bunch of classes, because that would defeat the purpose of unit-testing.
But not all classes do everything on their own, right? Most classes use other classes to do their work, and they kind of mediate between other classes, and add a bit of their own, to get the final result.
The point is - you don't care about how the classes your SUT depends on work. You care how your SUT works with those classes. That's why you stub or mock the classes your SUT needs. And you can use those mocks because you can pass them in as constructor parameters for your SUT.
With singletons - the bad thing is that the getInstance()
method is globally accessible. That means that you usually call it from within a class, instead of depending on an interface you can later mock. That's why it's impossible to replace it when you want to test your SUT.
The solution is not to use the sneaky public static MySingleton getInstance()
method, but to depend on an interface your class needs to work with. Do that, and you can pass in test doubles whenever you need to.