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

时间:2019-05-22 04:51:54

标签: c# mocking moq nsubstitute fakeiteasy

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

为什么Telerik JustMockTypemock Isolator之类的某些框架支持这些功能?并且我们不能在MoqFakeItEasyNSubstitute等中使用这些。

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

1 个答案:

答案 0 :(得分:4)

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

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

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

我不知道JustMock和TypeMock隔离器如何工作;我怀疑他们使用CLR的内部功能做了一些不可思议的事情,或者可能是动态重写代码(Pose就是这样做的:它将对指定方法的调用替换为对替换方法的调用)。

编辑:请参见this question about how TypeMock Isolator works。它使用探查器API劫持方法调用。如我所说,黑暗魔法^^