为什么 .NET (Core) 中的大多数模拟框架不能模拟静态和私有方法?

Ham*_*thi 4 c# moq mocking nsubstitute fakeiteasy

我的问题是关于此限制的技术原因,而不是关于如何修复它。

为什么像Telerik JustMockTypemock Isolator这样的框架支持这些功能,但我们不能在MoqFakeItEasyNSubstitute等中拥有这些功能?

单元测试中提到的项目是否不必要?

Tho*_*que 8

这是因为这些库的工作方式。当您使用 Moq、NSubstitute 或 FakeItEasy 模拟一个类时,它们会动态创建一个从该类继承并覆盖其方法的类。但是他们必须遵循平台的覆盖方法规则:

  • 根据定义,非虚拟方法不能被覆盖
  • 派生类无法访问私有方法,因此它们不能被覆盖(事实上,C# 甚至不允许它们是虚拟的,因为它没有意义)
  • 静态方法也不能被覆盖,因为它没有意义:多态性基于调用方法的实例的类型,而静态方法没有实例......

事实上,这些模拟库没有做任何你自己手动编写假/模拟类无法完成的事情;它们只是通过让您摆脱样板代码而变得更容易。出于同样的原因,您无法手动覆盖静态或非虚拟方法,这些库也无法覆盖。

我不知道 JustMock 和 TypeMock Isolator 是如何工作的;我怀疑他们用 CLR 的内部结构做了一些黑魔法,或者可能动态地重写代码(这就是Pose所做的:它将对指定方法的调用替换为对替换方法的调用)。

编辑:请参阅有关 TypeMock Isolator 如何工作的问题。它使用分析器 API 来劫持方法调用。正如我所说,黑魔法^^