生成服务模拟:RhinoMocks失败了吗?

时间:2012-06-26 08:53:24

标签: mocking moq rhino-mocks fakeiteasy nsubstitute

请参阅此代码:

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是自动生成的类中的非虚方法调用,它继承自NO接口。因此,根据常识,它不应该工作。 但确实如此。

问题是它是唯一可以做到这一点的(非商业)框架:

  • Rhino.Mocks工作,验证也有效
  • FakeItEasy说它找不到默认构造函数(可能只是错误的异常消息):No default constructor was found on the type SomeNamespace.TicketStoreService
  • Moq提供了理智和可理解的内容:Invalid setup on a non-virtual (overridable in VB) member: service=> service.DoSomething
  • Nsubstitute发出消息System.NotSupportedException: Cannot serialize member System.ComponentModel.Component.Site of type System.ComponentModel.ISite because it is an interface.

除了Moq之外,我真的很想知道这里有什么框架。 “花哨的新”框架似乎也有一个初始的打击,可能准备一些类型缓存和序列化的东西,而RhinoMocks以某种方式设法创建一个非常“苗条”的模拟没有递归。我不得不承认我不太喜欢RhinoMocks,但不幸的是,它在这里闪耀着光芒。

那么,有没有办法让它与更新的(非商业!)模拟框架一起工作,或者以某种方式得到一个理智的错误信息(描述我实际使用的6个参数中的哪一个在哪个方面有所不同)出了Rhino.Mocks?为什么Rhino.Mocks可以实现这一点,当显然每个Mocking框架都声明它只能在给定具体类时使用虚方法?

*让我们不要通过谈论像Extract&amp; Override等替代方法或像JustMock / TypeMock / Moles这样的运行时代理模拟框架或新的Fakes框架来破坏讨论,我知道这些,但这不是理想的解决方案,原因是超出这个主题。

1 个答案:

答案 0 :(得分:4)

您可以尝试Fody插件Virtuosity,它使所有成员都使用il编织虚拟,因此任何基于动态代理的库都可以使用它。检查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)

看起来这里还有其他事情发生。您是否能够发布一个独立的,最小的案例来重现这个?

最后,您提到的所有库都是开源的,因此选择您最喜欢的库并查看是否可以改进错误消息或性能会很棒。如果你没有为开源做出贡献之前看起来有点令人生畏,但项目上的人通常都很乐意尝试帮助任何有兴趣贡献的人。 :)