如何使用Rhino Mocks调用泛型方法?

时间:2010-09-09 16:21:51

标签: unit-testing mocking rhino-mocks

我有以下测试来验证我的存储库是否正在调用它的相应会话(我已经重写它以突出显示实际问题):

[Test]
    public void Why_Does_This_Fail()
    {
        var objectUnderTest = new SomeGenericsProblem();

        var fakeSession = MockRepository.GenerateMock<ISession>();
        fakeSession.Expect(s => s.Query<SomeClass>());

        objectUnderTest.NotWorking<SomeClass>();

        fakeSession.AssertWasCalled(t => t.Query<SomeClass>());
    }

但是当我运行测试时,我得到了这个:

  

System.InvalidOperationException:   呼叫无效,最后一次通话已经完成   使用过或没有打过电话(制作   确定你正在呼叫虚拟   (C#)/ Overridable(VB)方法)。(C#)/ Overridable(VB)方法)。

任何想法我在这里做错了什么?我正在嘲笑的会话是一个界面,所以 是虚拟/可覆盖的。

我觉得它与我的查询方法是通用的事实有关,但我不知道任何其他方式来表达我想要测试的内容。

另外,如果我删除了设置期望的部分(即这行代码:)

fakeSession.Expect(s => s.Query<SomeClass>());

我得到了一个同样令我困惑的异常:

  

System.InvalidOperationException:不   期望被设定为   验证,确保方法调用   在动作中是虚拟的(C#)/   overridable(VB.Net)方法calloverridable(VB.Net)方法调用

2 个答案:

答案 0 :(得分:2)

所以我弄清楚出了什么问题。

ISession来自NHibernate,我可能应该提到它。

这是至关重要的原因是因为

session.Query<T> 

(我正在尝试模拟),是扩展方法

Rhino Mocks显然具有模拟扩展方法的能力,因此它为什么会给我一个奇怪的错误。

所以希望我能够节省别人的时间和痛苦,试图找出为什么我的测试不会通过。

我读到的唯一解决方案是实际更改扩展方法的设计(我不能这样做,因为它是NHibernate的一部分),或者使用不同的模拟框架,如TypeMock。

答案 1 :(得分:0)

[Test]
public void Query_WhenCalled_CallsSessionQuery()
{
        // arrange
        var session = MockRepository.GenerateStub<ISession>();

        var r = new Repository(session);

        // act
        r.Query<SomeClass>();

        // assert
        session.AssertWasCalled(s => s.Query<SomeClass>());
}