【问题标题】:RhinoMocks is throwing InvalidOperationException in generic methodRhinoMocks 在泛型方法中抛出 InvalidOperationException
【发布时间】:2013-10-18 14:37:07
【问题描述】:

我想在我的测试中模拟一个类,这里​​是它的一部分界面:

interface IInventory
{
    Instrument[] GetAllInstrumentsAffectedByFixSide(int fixSideNumber);

    bool IsRegistered<T>(string name, int? fixSideNumber) where T : InventoryObject;
}

我的记录是这样的:

using (mockRepository.Record())
{
    inventory.GetAllInstrumentsAffectedByFixSide(0);
    LastCall.Return(new Instrument[0]);

    inventory.Expect(x => x.IsRegistered<TestInstrument>("ActivatorInstrument", null)).IgnoreArguments().Return(true)
}

但是当我在我的被测代码中写这个时:

TestHandler.Inventory.IsRegistered<TestInstrument>("ActivatorInstrument", null)

它抛出 InvalidOperationException。它抛出这个异常的地方很有趣——它是MethodInfo.GetGenericMethodDefinition()

它的来源是这样的:

public override MethodInfo GetGenericMethodDefinition()
{
    if (!IsGenericMethod)
        throw new InvalidOperationException();
    Contract.EndContractBlock();

    return RuntimeType.GetMethodBase(m_declaringType, RuntimeMethodHandle.StripMethodInstantiation(this)) as MethodInfo;
}

所以这个方法实际上是在非泛型方法上调用的。当我在里面放了一个断点,查看这个methodInfo是什么的时候,发现其实不是IsRegistered&lt;&gt;方法,而是GetAllInstrumentsAffectedByFixSide。

为什么 Rhino 试图在 IsRegistered&lt;&gt; 的模拟调用中为方法 GetAllInstrumentsAffectedByFixSide 调用 GetGenericMethodDefinition? GetGenericMethodDefinition 电话之前发生过。看起来只是混淆了这两种方法。

堆栈跟踪:

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 IInventoryProxy4a132be1cb07441cafba3f828d3ced66.IsRegistered[T](String name, Nullable`1 fixSideNumber)
at TestHandlerLibrary.DummyFixSideHandler.DoInitialization() in \RTX.Test.TestGear.DummyTestHandlerLibrary\DummyFixSideHandler.cs:line 87

更新我在问题中犯了一个错误:我实际上将期望设置为:

inventory.Expect(x => x.IsRegistered<TestInstrument>("ActivatorInstrument", null)).IgnoreArguments().Return(true);

当我将其更改为不带 .Expect 和 LastCall 的直接设置时 - 它确实有效。有什么想法吗?我已经更改了上面的代码,以反映问题。

【问题讨论】:

  • 您使用的是什么版本的 Rhino Mocks?我试图回忆历史,但我认为这是/曾经是犀牛模拟的已知错误。您能否为这个问题整理一个独立的、代码完整的示例,以便我们自己重现它?
  • 3.6.0 我可以尝试,但可能行不通——我有很多单元测试,那里有很多通用方法。由于某种原因,这只会引发异常。我还没有发现任何差异
  • @vcsjones 我更新了帖子,你能看一下吗?
  • 这个也很有趣:当我通过 .Expect() 或 .Stub() 等扩展方法设置期望时 - NEXT 方法失败,而不是我设置的方法

标签: c# generics rhino-mocks


【解决方案1】:

此问题已在 3.6.1 版中得到纠正

我不认为从 3.6.0 版本更新应该是一个问题,因为所有的结构都保留了

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-18
    • 1970-01-01
    • 2015-12-17
    • 2021-06-04
    • 1970-01-01
    • 2015-08-27
    • 1970-01-01
    相关资源
    最近更新 更多