Rhino Mocks存根和模拟只适用于接口?

Dmi*_*nov 21 .net unit-testing rhino-mocks mocking stubbing

Rhino Mocks存根和模拟只对接口有用,而不是具体的类吗?我花了很多时间试图让这段代码工作.我没想到存根的pubSubClient总是从类中调用Send方法.该方法有一些依赖项并抛出异常.

[Test]
public void Test01()
{
    PubSubMessage psm = new PubSubMessage(); 
    var pubSubClient = MockRepository.GenerateStub<PubSubClient>();
    pubSubClient.Stub(x => x.Send(psm)).IgnoreArguments().Return(null);
    // actual PubSubClient Send method throws exception
    // the rest of the test is skipped...
}
Run Code Online (Sandbox Code Playgroud)

但是,当我提取界面并使用IPubSubClient运行相同的测试时,它似乎按预期工作.

这是否意味着我必须为我想要使用Rhino模拟/存根的每个类提取接口?或者我在技术上或概念上遗漏了什么?

更新:好的,我似乎弄清楚了我缺少的部分: Rhino Mocks无法拦截对非虚方法的调用.所以,我想我要么使用接口,要么在具体类虚拟上使用每个方法.如果还有其他选择,请纠正我.

Jud*_*ngo 23

布莱恩使用部分嘲笑的答案是错误的.这不是部分嘲笑的原因.

Jon Erickson的回答大多是正确的:Rhino Mocks和Moq不能拦截非虚拟调用,也不能拦截静态方法或属性.这意味着你不能伪造以下内容:

DateTime.Now; // static property, can't fake static property
someClass.SomeNonVirtualMethod(); // can't fake non-virtual method
sealedClass.Foo(); // can't fake anything on sealed classes
Utilities.SomeStaticMethod(); // can't fake static methods
someList.Any(); // can't fake extension methods like Linq's .Any()
Run Code Online (Sandbox Code Playgroud)

正如Jon所说,TypeMock可以伪造这些.

应该注意的是,还有一个可以拦截所有调用的额外模拟框架:Microsoft Moles框架.它的工作方式与TypeMock相同,它使用.NET Profiler API来拦截调用.

鼹鼠是免费的(暂时).它也是测试版.Moles仅适用于Microsoft Pex工具.它的API明显不如TypeMock精致优雅的API.

  • 如果你声明部分嘲笑不是为了什么,那么在你的回答中说出它们的用途会更有帮助.部分模拟仅用于模拟类的一部分,这使得它们很方便(并且需要)模拟一个普通模拟无法处理它的Abstract类.这允许测试抽象方法.部分模拟(至少在Rhino中)将模拟任何类,并且不限于抽象类,但是请注意是否存在将在返回时调用的实现代码. (4认同)