为什么Rhino Mocks在存根上出错,但与模拟完全不同?

时间:2010-10-14 06:06:57

标签: c# rhino-mocks

我是犀牛模拟的新手,刚刚开始使用这个项目。

我正在测试一些调用外部方法的代码来获取一个IEnumerable的'Project',我有一个接口,以便我可以存根/模拟它。

在我的单元测试开始时测试一些迭代的代码(或调用Count(),两者都导致错误)IENumerable,我设置了一个存根实现

IJobProcess stub = MockRepository.Stub<IJobProcess>();
SetupResult.For(stub.CheckTeamMeetingInLastMonth(null)).IgnoreArguments().Return(true);
SetupResult.For(stub.GetOutstandingActions(null)).IgnoreArguments().Return(
                    new List<ProjectActionsDomain.DomainObjects.ProjectAction>()
                    );      

然而,这导致:

PmqccFormTests.GetFlagsReturnsIncompleteFlagWhenIncomplete : FailedSystem.InvalidOperationException : Previous method 'IEnumerator.MoveNext();' requires a return value or an exception to throw.
at Rhino.Mocks.Impl.RecordMockState.AssertPreviousMethodIsClose()
at Rhino.Mocks.Impl.RecordMockState.MethodCall(IInvocation invocation, MethodInfo method, Object[] args)
at Rhino.Mocks.MockRepository.MethodCall(IInvocation invocation, Object proxy, MethodInfo method, Object[] args)
at Rhino.Mocks.Impl.RhinoInterceptor.Intercept(IInvocation invocation)
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at System.Linq.Enumerable.Count(IEnumerable`1 source)
at PmqccDomain.DomainObjects.PmqccForm.GetFlags() in PmqccForm.cs: line 387
at PmqccUnitTests.PmqccFormTests.GetFlagsReturnsIncompleteFlagWhenIncomplete() in PmqccFormTests.cs: line 426 

但是,如果我将其更改为

        IJobProcess mock = MockRepository.GenerateMock<IJobProcess>();

        mock.Expect(x => x.GetOutstandingActions(null)).IgnoreArguments().Return(
            new List<ProjectActionsDomain.DomainObjects.ProjectAction>());
        mock.Expect(x => x.CheckTeamMeetingInLastMonth(null)).IgnoreArguments().Return(true);

它没有错误,我认为存根是一个基本没有对其结果断言的模拟?或者我错了吗? Rhino Mocks做什么不同,避免了使用模拟时的错误?

3 个答案:

答案 0 :(得分:5)

正如Jonny C强调的那样,我认为SetupResult与MockRepository.GenerarteStub不兼容。

SetupResult似乎与Rhino在使用lamba表达式之前使用的期望记录和回放功能一起使用。

首选方法是使用稍后介绍的Arrange-Act-Assert语法,但是在查看Rhino API时,很难说明使用什么用于AAA。

我所做的只是存在需要返回值的存根方法/属性,并声明最后调用了方法。

那应该是什么......

//Arrange
IJobProcess stub = MockRepository.GenerateStub<IJobProcess>();
stub.Stub(x => x.CheckTeamMeetingInLastMonth(null)).IgnoreArguments().Return(true);
stub.Stub(x => x.GetOutstandingActions(null)).IgnoreArguments().Return(
                new List<ProjectActionsDomain.DomainObjects.ProjectAction>()
                );   
//Act
-- Perform SUT --

//Assert
stub.AssertWasCalled(x => x.CheckTeamMeetingInLastMonth(someExpectedValue));

useage of SetupResult

usage of AAA

答案 1 :(得分:3)

我不确定如何使用SetupResult.For,但是要存根我通常会使用的方法

stub.Stub(j => j.CheckTeamMeetingInLastMonth(null))
.IgnoreArguments().Return(true);

做同样的事情你要做的事情。 mock.Stub()也可以用于同样的目的。

答案 2 :(得分:0)

需要注意的是

的对应部分
IJobProcess mock = MockRepository.GenerateMock<IJobProcess>();

IJobProcess stub = MockRepository.GenerateStub<IJobProcess>();

因此,为了直接进行比较,您可能希望尝试以这种方式进行存根,并查看是否使用相同的语法获得错误。

但是要回答你的问题,是的,那就是存根,我不知道为什么会失败(虽然我不熟悉你使用的存根语法)。在mailing list here上讨论的类似错误可能与此有关。