【发布时间】:2010-07-12 16:24:49
【问题描述】:
我是 mocking 的新手,所以我在这里可能完全错了,但我相信大多数 mocking 框架都依赖于接口。不幸的是,我们的大部分代码都没有使用接口。前几天我看到了一个 Java 中的 Mocking 框架,它重现了类\对象的字节码,以不调用其内部方法,但您仍然可以测试它是否正在调用这些方法。
我的问题是:.Net 是否有任何模拟框架可以做类似的事情?我正在寻找免费的东西,我不想要需要虚拟或抽象方法的东西。
【问题讨论】:
我是 mocking 的新手,所以我在这里可能完全错了,但我相信大多数 mocking 框架都依赖于接口。不幸的是,我们的大部分代码都没有使用接口。前几天我看到了一个 Java 中的 Mocking 框架,它重现了类\对象的字节码,以不调用其内部方法,但您仍然可以测试它是否正在调用这些方法。
我的问题是:.Net 是否有任何模拟框架可以做类似的事情?我正在寻找免费的东西,我不想要需要虚拟或抽象方法的东西。
【问题讨论】:
Microsoft Research 为此开发了Moles,它是 Pex 的一部分,但可以独立安装。它是免费的。网站上有一个很好的introductory article (pdf),它解释了如何模拟静态方法。他们需要一些时间才能找到您想要的东西(第 16 页,任务 3)。
Here 和 here(第 9 频道)您可以找到有关如何存根 DateTime.Now 的示例。使用 Moles,你可以模拟任何你想要的东西。
【讨论】:
TypeMock Isolator 可以模拟任何 .NET 类,但它不是免费的(甚至不便宜)。我不确定它是如何工作的,但它达到了相同的最终结果。
但大多数模拟框架并不完全依赖于接口;它们应该能够处理具体的类,尽管它们只能覆盖虚拟或抽象方法。
【讨论】:
Moq 和Rhino.Mocks 都可以使用类而不是接口,但模拟方法必须是虚拟的。 Mark Rushakoff 对 TypeMock 的回答是正确的 (+1)。
最好的选择是重构现有代码以提高可测试性(这可能需要一些时间)。我建议阅读 Michael Feathers 的 Working Effectively with Legacy Code。
【讨论】:
许多 .NET 模拟框架使用 Castle Dynamic Proxy 在运行时创建模拟。因此,只允许模拟接口/虚拟方法的限制来自 Castle,我认为植根于 CLR。 MOQ 和 RhinoMocks 都能够模拟虚拟方法,这是最好的。
类和接口都可以 代理,但只有虚拟成员 可以拦截。
我的建议是开始为那些需要模拟的类创建抽象基并让具体类扩展它。然后可以传递和模拟抽象基础。这确实是一个不太复杂的重构练习。
【讨论】: