I’ve encountered a problem on how Rhino.Mocks handles unexpected
method calls on mocks in certain situations where there is a mixture
of generic and non-generic methods called.
Here’s an example piece of code that reproduces the problem:
public interface IFoo
{
void GenericMethod<T>();
void NonGenericMethod();
}
public static void Main()
{
MockRepository mockRepos = new MockRepository();
IFoo mock = mockRepos.StrictMock<IFoo>();
mock.NonGenericMethod();
mockRepos.ReplayAll();
mock.NonGenericMethod();
mock.GenericMethod<object>(); // Should throw
ExpectationViolationException,
// but
throws InvalidOperationException.
}
There’s no expectation for the call to GenericMethod(), so I would
expect an ExpectationViolationException, but instead an
InvalidOperationException is thown with the following stack trace:
at System.Reflection.RuntimeMethodInfo.GetGenericMethodDefinition()
at Rhino.Mocks.MethodRecorders.UnorderedMethodRecorder.MethodsEquals
(MethodInfo method, ProxyMethodExpectationTriplet triplet)
at
Rhino.Mocks.MethodRecorders.UnorderedMethodRecorder.GetAllExpectationsForProxyAndMethod
(Object proxy, MethodInfo method)
at
Rhino.Mocks.MethodRecorders.UnorderedMethodRecorder.CalcExpectedAndActual.Calculate
(Object proxy, MethodInfo method, Object[] args)
at
Rhino.Mocks.MethodRecorders.UnorderedMethodRecorder.CalcExpectedAndActual..ctor
(UnorderedMethodRecorder parent, Object proxy, MethodInfo method,
Object[] args)
at
Rhino.Mocks.MethodRecorders.UnorderedMethodRecorder.UnexpectedMethodCall
(IInvocation invocation, Object proxy, MethodInfo method, Object[]
args)
at
Rhino.Mocks.MethodRecorders.UnorderedMethodRecorder.DoGetRecordedExpectation
(IInvocation invocation, Object proxy, MethodInfo method, Object[]
args)
at
Rhino.Mocks.MethodRecorders.MethodRecorderBase.GetRecordedExpectation
(IInvocation invocation, Object proxy, MethodInfo method, Object[]
args)
at Rhino.Mocks.Impl.ReplayMockState.DoMethodCall(IInvocation
invocation, MethodInfo method, Object[] args)
at Rhino.Mocks.Impl.ReplayMockState.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 IFooProxyf637724feb334bf5bc3b967248b5653b.GenericMethod[T]()
I haven’t seen this exception when tests pass, it has only happened
when an expectation violation failure is produced. It's still
frustrating not to get a clear expectation violation message in this
case. All I can deduce from this failure is that something unexpected
was probably called.
Looking at the stack trace and source code (from github), I suspect
that UnorderedMethodRecorder.MethodsEquals() might be defective:
private static bool MethodsEquals(MethodInfo method,
ProxyMethodExpectationTriplet triplet)
{
if(method.IsGenericMethod==false)
return triplet.Method == method;
return triplet.Method.GetGenericMethodDefinition() ==
method.GetGenericMethodDefinition();
}
What if method.IsGenericMethod==true, but
triplet.Method.IsGenericMethod==false? In this case
triplet.Method.GetGenericMethodDefinition() is called and that throws
InvalidOperationException because the method is not generic.
Does anyone agree that this is a defect?
This applies to versions 3.6 and 3.5 at least.
Thanks.
-Juhani
--
You received this message because you are subscribed to the Google Groups
"Rhino.Mocks" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/rhinomocks?hl=en.