尝试使用Moq设置索引器属性时,基础Castle库会抛出InvalidCastException。我使用的是Moq 4.0.10827,详情如下。如果有人能帮助我进行简单的测试(下面),请提前致谢。我正在用Moq重写单元测试,我正在尝试重新进行以下方法的测试:
public INetwork GetInputNetwork(IInputPortMgr inPortMgr)
{
var port = inPortMgr[0];
return port.InputNetwork;
}
IInputPortMgr接口如下:
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
任何想法或任何人都可以指出我正确的方向?感谢。
答案 0 :(得分:2)
它是Castle DynamicProxy版本中的bug,它被合并到moq二进制文件(Castle.Core 2.5.0.0)中。它看起来会影响接受params
参数的属性。我假设IInputPort
装饰有这样的属性,因为没有提供代码?
您可以使用最新版本的Castle.Core(3.0.0.0)(理想)编译moq。
或(不太理想),从Google Code下载最新的moq版本,其中包含未嵌入Castle.Core
的moq.dll版本。在项目中引用此项和Castle.Core 3.0.0.0,并在app.config中添加以下绑定重定向。由于这是一个主要的升级点,我不能保证它的向后兼容性,但我用你的代码测试了这个(和IInputPort
界面装饰了一个表明2.5.0.0中的bug的属性)并且它有效。
<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>