c# - 对索引器属性使用 Moq 会导致 CaSTLe 出现 InvalidCastException

标签 c# moq

当尝试使用 Moq 设置索引器属性时,底层 CaSTLe 库会抛出 InvalidCastException。我使用的是 Moq 4.0.10827,详细信息如下。如果有人可以帮助我运行简单的测试(如下),请提前致谢。我正在使用 Moq 重写单元测试,并尝试使用以下方法重新进行测试:

public INetwork GetInputNetwork(IInputPortMgr inPortMgr)
{
    var port = inPortMgr[0];
    return port.InputNetwork;
}

IInputPortMgr接口(interface)如​​下:

public interface IInputPortMgr
{        
    IInputPort this[int index] { get; }
}

我编写的测试(并尝试了多种变体)可以总结为:

[Test]
public void GetInputNetwork_Returns_InputNetwork_From_InputPort()
{
    var mockInPortMgr = new Mock<IInputPortMgr>();
    var mockInPort = new Mock<IInputPort>();
    var mockNet = new Mock<INetwork>();

    mockInPortMgr.Setup(m => m[0]).Returns(mockInPort.Object);  // exception here
    mockInPort.Setup(m => m.InputNetwork).Returns(mockNet.Object);

    // Assertions Here
}

但是运行时单元测试失败,因为该行抛出了异常

mockInPortMgr.Setup(m => m[0]).Returns(mockInPort.Object);

异常的详细信息是:

System.InvalidCastException : Unable to cast object of type 'System.Collections.ObjectModel.ReadOnlyCollection`1[System.Reflection.CustomAttributeTypedArgument]' to type 'System.Array'.
at System.Reflection.Emit.CustomAttributeBuilder.EmitValue(BinaryWriter writer, Type type, Object value)
at System.Reflection.Emit.CustomAttributeBuilder.InitCustomAttributeBuilder(ConstructorInfo con, Object[] constructorArgs, PropertyInfo[] namedProperties, Object[] propertyValues, FieldInfo[] namedFields, Object[] fieldValues)
at Castle.DynamicProxy.AttributeUtil.CreateBuilder(CustomAttributeData attribute)
at Castle.DynamicProxy.AttributeUtil.<GetNonInheritableAttributes>d__0.MoveNext()
at Castle.DynamicProxy.Generators.MetaProperty.BuildPropertyEmitter(ClassEmitter classEmitter)
at Castle.DynamicProxy.Contributors.CompositeTypeContributor.ImplementProperty(ClassEmitter emitter, MetaProperty property, ProxyGenerationOptions options)
at Castle.DynamicProxy.Contributors.CompositeTypeContributor.Generate(ClassEmitter class, ProxyGenerationOptions options)
at Castle.DynamicProxy.Generators.InterfaceProxyWithoutTargetGenerator.GenerateType(String typeName, Type proxyTargetType, Type[] interfaces, INamingScope namingScope)
at Castle.DynamicProxy.Generators.InterfaceProxyWithTargetGenerator.GenerateCode(Type proxyTargetType, Type[] interfaces, ProxyGenerationOptions options)
at Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, IInterceptor[] interceptors)
at Moq.Proxy.CastleProxyFactory.CreateProxy(ICallInterceptor interceptor, Type[] interfaces, Object[] arguments)
at Moq.Mock`1.<InitializeInstance>b__0()
at Moq.Mock`1.InitializeInstance()
at Moq.Mock`1.OnGetObject()
at Moq.Mock`1.get_Object()
at Tests.Psi.Type6.Fx.Type6Fixture.GetInputNetwork() in Type6Fixture.cs: line 293  

有什么想法或者有人能指出我正确的方向吗?谢谢。

最佳答案

这是一个 bug在合并到 moq 二进制文件中的 CaSTLe DynamicProxy 版本中 (CaSTLe.Core 2.5.0.0)。它看起来会影响接受 params 参数的属性。我假设 IInputPort 用这样的属性装饰,因为未提供代码?

您可以使用最新版本的 CaSTLe.Core (3.0.0.0) 编译起订量(理想)。

或者(不太理想),从 Google Code 下载最新的最小起订量版本,其中包括未嵌入 CaSTLe.Core 的 moq.dll 版本。在您的项目中引用此内容以及 Castle.Core 3.0.0.0并在您的 app.config 中添加以下绑定(bind)重定向。由于这是一个重要的升级点,我不能保证它的向后兼容性,但我用您的代码(以及用一个在 2.5.0.0 中显示错误的属性装饰的 IInputPort 接口(interface))对此进行了测试,并且它起作用了。

  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Castle.Core" 
                          publicKeyToken="407dd0808d44fbdc" 
                          culture="neutral" />
        <bindingRedirect oldVersion="2.5.0.0" 
                         newVersion="3.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>

关于c# - 对索引器属性使用 Moq 会导致 CaSTLe 出现 InvalidCastException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10922637/

相关文章:

c# - 如何正确测试这个? (C#、NUnit、最小起订量)

c# - 如何对 WPF 用户控件的 View 模型进行单元测试

c# - 最小起订量验证链接

c# - 在 C# Android 应用程序中设置 TextView 内的超链接

c# - 如何从 Entity Framework 数据库中获取对象列表?

C# 测试 - 构造函数调用中的模拟类

c# - 在最小起订量中使用 Match.Create

c# - 在编程中处理属性

c# - 使用 .Net 列出 Google Drive V2 中的所有文件和文件夹

c# - 为什么 switch 表达式会从周围的上下文中推断出表达式类型,而其他类型不明确的表达式却不会?