Singleton and unit testing

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 impossible to substitute a mock implementation for a singleton unless it implements an interface that serves as its type.

Can anyone explain the why this is so ?


You could use reflection to reset your singleton object to prevent tests from affecting each other.

@Before
public void resetSingleton() throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
   Field instance = MySingleton.class.getDeclaredField("instance");
   instance.setAccessible(true);
   instance.set(null, null);
}

Ref: unit-testing-singletons


Mocks require interfaces, because what you're doing is replacing the real underlying behavior with an imposter that mimics what you need for the test. Since the client only deals with an interface reference type, it doesn't need to know what the implementation is.

You can't mock a concrete class without an interface, because you can't replace the behavior without the test client knowing about it. It's a completely new class in that case.

It's true for all classes, Singleton or not.


I think it actually depends on the implementation of the singleton access pattern .

For example

MySingleton.getInstance()

Might be very dificult to test while

MySingletonFactory mySingletonFactory = ...
mySingletonFactory.getInstance() //this returns a MySingleton instance or even a subclass

Doesn't provide any information about the fact that its using a singleton. So you can freely replace your factory.

NOTE : a singleton is defined by being only one instance of that class in an application, however the way it's obtained or stored doesn't have to be through static means.

链接地址: http://www.djcxy.com/p/78796.html

上一篇: 为什么单身人士课很难测试?

下一篇: 单身和单元测试