【问题标题】:How does a mocking framework work?模拟框架如何工作?
【发布时间】:2013-03-18 20:24:55
【问题描述】:

大多数模拟框架只能模拟接口,有些可以模拟类的虚拟方法。一些 Java 模拟框架甚至能够模拟静态类。

例如犀牛模型:

var mock = MockRepository.GenerateMock<..>();

生成模拟方法中有什么“魔法”? C# 模拟框架不允许模拟静态类有什么原因吗?或者这只是一个“设计选择”?

【问题讨论】:

  • PS:谷歌搜索该主题只为我提供了如何使用模拟框架的教程,而不是我正在寻找的内容
  • 试试“哦,看看我在空中挥手我是一个框架......哦,太特别了”:)
  • moq 是开源的。
  • 通常mock是一个类的实例,因此它是一个静态类是没有意义的,因为它们没有实例。结果,生成静态模拟的技术可能会完全不同。因此,对静态类的支持可能需要不同的 API 和额外的努力来支持同一框架。这是我有根据的猜测。

标签: c# mocking implementation


【解决方案1】:

查看此类框架的源代码并自己找到答案实际上是非常有趣和令人着迷的。 Rhino Mocks 以及 Moqmany others 是开源的。我肯定会建议深入其中之一。

至于内部实现(来自here):

但是,框架不能模拟非虚拟方法,因此我们需要将 TouchIron 方法设为虚拟。原因很深:Rhino Mocks 使用Castle Dynamic Proxy 来处理代理它需要模拟的类型,而动态代理无法拦截对非虚拟、非抽象方法的调用。

【讨论】:

  • 这可能解释了为什么不支持静态类,因为它无法重定向/代理静态方法调用。可能需要一种完全不同的方法。
  • yo thx 很多,阅读 atm 内容并尝试在 Moq 上找到“下载源”按钮 :)。 thx 到目前为止,稍后会回来
【解决方案2】:

大多数开源模拟框架都使用Castle Windsor's Dynamic Proxy 在运行时自动生成一个类型,可以对其进行编程以实现预期行为。这就是为什么大多数框架都需要接口或抽象类的原因——它们无法模拟任何不是虚拟方法的东西。

还有其他(商业)模拟框架确实可以模拟静态和常规(密封)类,包括基于非托管 CLR Profiler API 的 CLR 类型。基本上,模拟框架充当分析器,并且能够在 JIT 编译之前修改内存中的 MSIL 指令。这就是它能够用预定义值替换任何方法的主体的方式。其中一些框架是免费的*(Microsoft Fakes,Visual Studio 2012 Ultimate 的一部分),另一些是付费产品,例如 Typemock

【讨论】:

    【解决方案3】:

    几乎所有 .NET 模拟框架都利用了Castle Windsor's Dynamic Proxy 功能。我会建议你经历一些。

    【讨论】:

      猜你喜欢
      • 2017-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-12
      • 2016-02-24
      • 1970-01-01
      • 2016-04-09
      相关资源
      最近更新 更多