C# 单元测试单例

C# 单元测试单例,c#,.net,unit-testing,singleton,C#,.net,Unit Testing,Singleton,我有一个包含对统计对象引用的单例 当我在使用该单例的程序上运行两个单元测试时——测试之间保持的值 我认为当我在做Program.Main()时,它会在单元测试之间重新开始,但不知怎的,它会记住上次测试的结果 如何编写相互隔离的单元测试(我不想要clean()函数-我希望它以新的“一切”重新开始),看看这个 我还建议使用模拟框架,如 为了隔离你的测试我在这里写了一篇文章: TL;博士: 从单例中提取接口(即使您不拥有它),并使您的类针对该接口而不是单例实例工作 根据您是否拥有Singleton,您

我有一个包含对统计对象引用的单例

当我在使用该单例的程序上运行两个单元测试时——测试之间保持的值

我认为当我在做Program.Main()时,它会在单元测试之间重新开始,但不知怎的,它会记住上次测试的结果

如何编写相互隔离的单元测试(我不想要clean()函数-我希望它以新的“一切”重新开始),

看看这个

我还建议使用模拟框架,如


为了隔离你的测试

我在这里写了一篇文章:

TL;博士:

  • 从单例中提取接口(即使您不拥有它),并使您的类针对该接口而不是单例实例工作
  • 根据您是否拥有Singleton,您可以让它实现该接口,或者您需要一个简单的适配器

  • 简短版本:不要把你的单例写成单例。将它们作为普通类编写,并通过控制反转容器调用它们,在该容器中,您将该类配置为单例


    这样,您就可以很好地对类进行单元测试,如果您今天或明天决定singleton不是该类的正确生活方式,只需修改IoC容器的配置。

    当尝试测试singleton本身时,以下可能是一个可能的解决方案:

    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
        }
    }
    
    因此,在您的单元测试框架中,您可以在每次单元测试之前调用
    Singleton.resetForTesting()


    注意:这种方法的缺点是没有代码级别的限制可以阻止某人在生产代码中调用此方法,即使它只用于测试代码。因此,您必须依赖文档将其传达给其他人。

    您可以向singleton类添加属性setter,以重新分配singleton实例。这样,在测试中,您可以存根/模拟您的单例

    请添加一些代码示例这是singleton的问题之一:)您可以重置singleton(通常通过使用反射将_实例指针设置为null),或者您需要考虑将其加载到自己的应用程序域中进行测试…@forsvarir:这是正确的答案。为什么要发表评论?@razelbe:我认为这不是一个答案,它是一个观察结果,是一个指向正确方向的指针。答案会有更多的实质内容:0)您使用的是哪个单元测试框架?您链接到的问题是关于OP得到的一个异常,但该问题的链接包含了许多与此问题相关的有用链接。您可能需要更新您的超链接。确实如此。我想帮你,帮你。:)每个测试创建一个新的
    AppDomain
    相当困难。例如,NUnit会为每个测试会话创建一个新的AppDomain(一次通过所有选定的测试)。然后,NUnit必须将其代码注入到
    AppDomain
    中才能运行测试。这不是小事。你不能仅仅创建一个新的,并期待它神奇地运行。你必须让你的代码在里面运行。总的来说,这个答案是有可能的,但我不同意“这应该不是太难的部分”。我会检查这个控制反转容器-尽管我没有时间投资于此。最后,仍然存在一个单例,我将验证此设计模式如何解决此问题。谢谢您可以通过将
    resetForTesting
    方法设置为内部,并使包含测试类的程序集可以看到内部,来添加限制。看这个。