unit testing中的静态类/方法/属性,是否停止

更新

应该在unit testing开发环境中使用静态类/方法/属性,因为如果不引入再次无法测试的包装器就无法测试它吗?

另一种情况是,当在unit testing目标内使用静态成员时,静态成员不能被模拟。 因此,在测试unit testing目标时,您必须测试静态成员。 您希望在静态成员执行计算时将其隔离。

测试静态方法与测试任何其他方法没有什么不同。 将静态方法作为另一个测试模块中的依赖项引发了问题(正如已经提到的那样 – 你不能使用免费工具来模拟/存根)。 但是,如果静态方法本身经过unit testing,您可以简单地将其视为可靠的组件 。

总的来说,在以下情况下,使用静态方法没有任何错误(例如,它不会中断unit testing/ TDD):

  • 它是简单的输入输出法(各种“计算这个给出的”
  • 它是可靠的 ,我们的意思是它是由你unit testing的,或来自你认为可靠的第三方来源(例如, Math.Floor可能被认为是可靠的 – 使用它不应该提出“注意,它是静态的!”警告;有人可能认为微软会做它的工作)

静态方法会导致问题,应该避免吗? 基本上只有当他们与/ 做某些事情无法控制 (或模仿)时:

  • 各种文件系统,数据库,网络依赖
  • 从内部调用的其他(可能更复杂的)静态方法
  • 几乎任何你的模拟框架都无法按常规处理

编辑: 关于静态方法何时使unit testing变得困难的两个例子

1

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

你如何处理File.ReadAllText ? 这显然会转到文件系统来检索文件内容,这在unit testing时是主要的禁忌。 这是具有外部依赖性的静态方法的示例。 为避免这种情况,您通常会在文件系统api周围创建包装器,或者只是将其作为依赖项/委托注入。

2

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

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

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

静态方法可以进行unit testing。 他们不能被嘲笑(通常;有一些框架可以像Moles一样做到这一点。

你不能模拟静态方法/属性。 因此,当您的classA使用classA某个静态成员时,您无法classA测试classA

更新:我没有看到任何将一些静态类包装到对象中的问题。 它不需要很多时间,但它允许您减少系统中的耦合。

从技术上讲,您可以使用PowerMock在Java中模拟静态方法,但如果您需要这样做,我会认真地建议您重构代码。 我认为静态方法应该始终是private并且只能在它们定义的类中使用,以用于内部目的。 我认为公开暴露静态方法作为代码气味 。

无论编程语言如何,我都会发现这种威胁,但由于我的日常生活与PHP有关,因此这里有很好的资源来处理PHP上的静态方法http://docs.mockery.io/en/latest/reference/public_static_properties.html