Unit testing singletons

拈花ヽ惹草 提交于 2019-12-18 19:23:18

问题


I have a singleton that contains reference to statistics 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"),


回答1:


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.




回答2:


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.



回答3:


look at this Unit testing with singletons

also I would reccomand to use the mocking frameworks like Moq

for isolation your test




回答4:


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.




回答5:


You can add property setter to your singleton class that will reassign singleton instance. This way in tests you can stub/mock your singleton.



来源:https://stackoverflow.com/questions/5897681/unit-testing-singletons

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!