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

标签 c# java unit-testing tdd

是否应该在单元测试开发环境中使用静态类/方法/属性,因为如果不引入同样不可测试的包装器就无法对其进行测试?

另一种情况是,当在单元测试目标中使用静态成员时,无法模拟静态成员。因此,您必须在测试单元测试目标时测试静态成员。当静态成员执行计算时,您希望将其隔离。

最佳答案

测试静态方法与测试任何其他方法没有什么不同。在另一个测试模块中将静态方法作为 依赖 会引发问题(正如已经提到的 - 您不能使用免费工具模拟/ stub 它)。但是如果静态方法本身是单元测试的,你可以简单地 treat it as working, reliable component .

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

  • 很简单,输入输出的方法(各种“计算这个给定”)
  • 它是可靠的,我们的意思是它要么是经过您的单元测试,要么来自您认为可靠的第 3 方来源(例如,Math.Floor 可能被认为是可靠的- 使用它不应引发“小心,它是静态的!” 警告;人们可能会认为微软已经完成了它的工作)

什么时候静态方法会导致问题并且应该避免?基本上只有当他们与/做一些你无法控制的事情(或模拟)时:

  • 各种文件系统、数据库、网络依赖项
  • 从内部调用的其他(可能更复杂的)静态方法
  • 几乎所有你的模拟框架无法正常处理的事情

编辑: 关于静态方法何时使单元测试变得困难的两个示例

1

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

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

2

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

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

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

关于c# - 单元测试中的静态类/方法/属性,停止与否,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10632975/

相关文章:

java - 如何获取用于编写自定义 Lombok 转换的 org.mangosdk.spi.ProviderFor 依赖项?

java - MySQL 不使用 netbeans 将插入推送到数据库中

ios - 如何在 iOS 测试中实际使用 Stub 或 Mocking 对象?

c# - 映射项目时 AutoMapper 中的事件

c# - 我如何在 c# 中使用键对字典进行排序---是否可以使用 LINQ?

java - 相同的 XML,不同的行为

angular - 如何在 Angular 单元测试中模拟函数中的服务调用?

javascript - Angular 组件的测试因超时而失败

c# - WPF:从模型MVVM关闭窗口

c# - 如何遍历 div 以重置链接的委托(delegate)?