单元测试中的静态类/方法/属性,是否停止 - c#

考虑到没有引入不能再次测试的包装器就无法测试的方法,是否应该在单元测试开发环境中使用静态的类/方法/属性?
另一种情况是,在单元测试目标中使用静态成员时,无法模拟静态成员。因此,在测试单元测试目标时,您必须测试静态成员。当静态成员执行计算时,您想隔离它。

参考方案

测试静态方法与测试任何其他方法没有什么不同。将静态方法作为依赖关系在另一个经过测试的模块中会引发问题(如前所述-您无法使用免费工具对其进行模拟/存根)。但是,如果静态方法本身已经过单元测试,则只需treat it as working, reliable component即可。

总体而言,在以下情况下,使用静态方法没有任何问题(例如,它不会破坏单元测试/ TDD):

  • 这是简单的输入输出方法(各种“给定的计算”)
  • 是可靠的,也就是说我们已经对它进行了单元测试,或者来自您认为可靠的第三方来源(例如Math.Floor可能被认为是可靠的-使用它不应引发“注意,这是静态的!”警告);可能会假设微软完成了工作)
  • 静态方法何时会引起问题,应避免使用?基本上,只有当他们与/ 互动时,您才能控制(或模拟):

  • 各种文件系统,数据库,网络依赖项
  • 内部调用的其他(可能更复杂的)静态方法

  • 您的模拟框架无法正常处理的几乎所有内容
  • 编辑:两个有关何时静态方法使单元测试变得困难的示例

    1

    public int ExtractSumFromReport(string reportPath)
    {
         var reportFile = File.ReadAllText(reportPath);
         // ...
    }
    

    您如何处理File.ReadAllText?很显然,这将进入文件系统以检索文件内容,这在单元测试时是主要的禁止。这是具有外部依赖关系的静态方法的示例。为了避免这种情况,通常可以围绕文件系统api创建包装器,或者只是将其作为依赖项/委托注入。

    2

    public void SaveUser(User user)
    {
        var session = SessionFactory.CreateSession();
        // ...
    }
    

    那这个呢?会话是非平凡的依赖关系。当然,它可能是ISession出现的,但是如何强制SessionFactory返回模拟?我们不能。而且我们也无法创建易于确定的会话对象。

    在上述情况下,最好完全避免使用静态方法。

    如何模拟保管库hvac.Client()方法 - python

    在这里,我正在使用unittest框架和Python。def getsomevalue(name): client = hvac.Client(url ="http://1.2.3.4:31485",token = "abcdefghijkkk") sampledata= client.read('secre…

    Java:正则表达式模式匹配器是否有大小限制? - java

    我的模式类似于OR:“word1 | word2 | word3”我大约有800个字。可能有问题吗? 参考方案 您仅受记忆和理智的限制。 :)

    Java:线程池如何将线程映射到可运行对象 - java

    试图绕过Java并发问题,并且很难理解线程池,线程以及它们正在执行的可运行“任务”之间的关系。如果我创建一个有10个线程的线程池,那么我是否必须将相同的任务传递给池中的每个线程,或者池化的线程实际上只是与任务无关的“工人无人机”可用于执行任何任务?无论哪种方式,Executor / ExecutorService如何将正确的任务分配给正确的线程? 参考方案 …

    JAVA:字节码和二进制有什么区别? - java

    java字节代码(已编译的语言,也称为目标代码)与机器代码(当前计算机的本机代码)之间有什么区别?我读过一些书,他们将字节码称为二进制指令,但我不知道为什么。 参考方案 字节码是独立于平台的,在Windows中运行的编译器编译的字节码仍将在linux / unix / mac中运行。机器代码是特定于平台的,如果在Windows x86中编译,则它将仅在Win…

    什么是将数组从C#返回到javascript的最佳(简单明了)方法 - c#

    我知道这里有很多类似的问题,但是我没有发现有人问完全相同的问题。我正在使用ASP.NET和MVC4开发项目。我正在使用aspx作为视图引擎。我的视图中有一个javascript代码,该代码获得了一个值表,并根据它们创建了一个图形。我使用下面的查询从数据库中获取这些值 var query = from b in db.SchoolTestsPerModuleP…