tags:

views:

57

answers:

3

I'm fairly new to rhino Mocks, just started using it this project.

I am testing some code which calls an external method to get an IEnumerable of 'Project', which I've got an interface for it so that I can stub/mock it out.

at the start of my unit test that tests some of the code that iterates over (or calls Count(), both cause the error) that IENumerable, I setup a stub implementation

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>()
                    );      

This however results in:

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 

However, if I change this to

        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);

It does not error, I thought a stub was a mock that didn't assert on its results basically? or am I wrong there? What does Rhino Mocks do differently that avoids the error when using a mock?

A: 

One thing to note is that the counterpart to

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

is

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

So to compare directly you might want to try stubbing that way and see if you get the error using the same syntax.

But to answer your question, yeah that's what a stub is, I don't know why that's failing (although I'm not familiar with the stub syntax you used). There's a similar bug discussed on a mailing list here, could be related to that.

Grant Crofton
Thanks for pointing that out - I just changed it from the _mockRepository variable I had to MockRepository but still get the same thing
RodH257
+3  A: 

I'm not sure exactly how SetupResult.For is used, but to stub a method I would normally use

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

to do the same thing you're trying to do. mock.Stub() works for the same purpose too.

Jonny Cundall
+2  A: 

As Jonny C has highlighted I believe that SetupResult is not compatible with MockRepository.GenerarteStub.

SetupResult seemsed to be used with the expect-record and playback functionality that Rhino used before lamba expressions were used.

The preferred way is to use the Arrange-Act-Assert syntax that was introduced later however when looking at the Rhino API it is hard to tell what to use for AAA.

What I do is to only stub methods/properties that need to return a value and assert that methods were called at the end.

so what should work is...

//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

aqwert
Thanks, the AAA syntax is a bit confusing, so much in the API seems to do the same thing, but slightly different. Like MockRepository.Stub vs GenerateStub.. confusing. Mock.Expect got it to work for me.
RodH257