查看这段代码:
TicketStoreService fakeTicketStoreService =
MockRepository.GenerateMock<TicketStoreService>();
fakeTicketStoreService.Expect(service => service.DoSomething(Arg.Is(new Guid()))
.Return(new Guid());
fakeTicketStoreService.DoSomething(Arg.Is(new Guid()));
fakeTicketStoreService.VerifyAllExpectations();
请注意,DoSomething
是自动生成的类中的非虚拟方法调用,它继承自任何接口(interface)。因此,根据常识,它不应该起作用。 但确实如此。
问题是它是唯一可以做到这一点的(非商业)框架:
- Rhino.Mocks 有效,验证也有效
- FakeItEasy 说它找不到默认构造函数(可能只是错误的异常消息):
在 SomeNamespace.TicketStoreService 类型上找不到默认构造函数
- Moq 提供了一些理智且易于理解的内容:
非虚拟(可在 VB 中重写)成员上的无效设置:service=> service.DoSomething
- Nsubstitute 给出一条消息
System.NotSupportedException:无法序列化 System.ComponentModel.ISite 类型的成员 System.ComponentModel.Component.Site,因为它是一个接口(interface)。
我真的很想知道除了 Moq 之外的框架发生了什么。 “奇特的新”框架似乎也有一个初始的性能命中,可能准备一些类型缓存和序列化的东西,而 RhinoMocks 以某种方式设法创建一个非常“ slim ”的模拟而不需要递归。我不得不承认我不太喜欢RhinoMocks,但不幸的是,它在这里闪闪发光。
那么,有没有办法让它与更新的(非商业!)模拟框架一起工作,或者以某种方式获得合理的错误消息(描述我实际使用的 6 个参数中的哪一个是不同的? )出自Rhino.Mocks?为什么 Rhino.Mocks 能够实现这一点,显然每个 Mocking 框架都声明它只能在给定具体类时使用虚拟方法?
*我们不要通过谈论 Extract&Override 等替代方法或 JustMock/TypeMock/Moles 等运行时代理模拟框架或新的 Fakes 框架来破坏讨论,我知道这些,但由于除此之外的原因,这将是不太理想的解决方案主题。
最佳答案
您可以尝试Fody插件Virtuosity这使得所有成员都使用 il weaving 进行虚拟化,因此任何基于代理的动态库都可以使用它。检查Fody example了解连接起来涉及到什么。
至于为什么 Rhino Mocks 有效,我无法理解:
[Test]
public void FieldTest() {
var fakeTicketStoreService = MockRepository.GenerateMock<TicketStoreService>();
fakeTicketStoreService.Expect(service => service.DoSomething(Arg.Is(new Guid()))).Return(new Guid());
fakeTicketStoreService.DoSomething(Arg.Is(new Guid()));
fakeTicketStoreService.VerifyAllExpectations();
}
public class TicketStoreService {
public Guid DoSomething(Guid guid) { return guid; }
}
它失败了:
System.InvalidOperationException : Invalid call, the last call has been used or no call has been made (make sure that you are calling a virtual (C#) / Overridable (VB) method).
at Rhino.Mocks.LastCall.GetOptions()
at Rhino.Mocks.RhinoMocksExtensions.Expect(T mock, Function`2 action)
看来这里还发生了其他事情。您能发布一个独立的、最小的案例来重现这一点吗?
最后,您提到的所有库都是开源的,因此最好选择您最喜欢的一个,看看是否可以改进错误消息或性能。如果您之前没有为开源做出过贡献,那么这似乎有点令人畏惧,但项目中的人们通常非常乐意尝试帮助任何有兴趣做出贡献的人。 :)
- Moq source
- FakeItEasy source
- NSubstitute source
- Rhino Mocks source (我想这就是它现在的家)
关于mocking - 生成的服务模拟 : everything but RhinoMocks fails?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11203833/