Unit testing singletons
I have a singleton that contains reference to statistic开发者_如何学运维s object.
When I run couple of unit test on the program that uses that singleton - the values sustained between the tests.
I though that when I'm doing Program.Main() it all starts over between unit tests, but somehow it remembers the results from last test.
How can I write unit tests that will be isolated from each other (I don't want clean() functions - I want it to start over with new "everything"),
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.
I wrote a post about that here: http://pvlerick.github.io/2017/03/how-to-get-rid-of-a-singleton
TL;DR:
- 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;
- 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.
look at this Unit testing with singletons
also I would reccomand to use the mocking frameworks like Moq
for isolation your test
You can add property setter to your singleton class that will reassign singleton instance. This way in tests you can stub/mock your singleton.
精彩评论