When trying to use Moq to setup an indexer property, the underlying Castle library throws an InvalidCastException. I am using Moq 4.0.10827, the details follow. Thanks in advance if anyone can help me get the simple test (below) to run. I am rewriting unit tests with Moq and I am trying to re-do the test for the following method:
public INetwork GetInputNetwork(IInputPortMgr inPortMgr)
{
var port = inPortMgr[0];
return port.InputNetwork;
}
The IInputPortMgr interface is as follows:
public interface IInputPortMgr
{
IInputPort this[int index] { get; }
}
The test I wrote (and tried numerous variations) can be summarized by:
[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
}
But when run the unit test fails because an exception is thrown by the line
mockInPortMgr.Setup(m => m[0]).Returns(mockInPort.Object);
The details of the exception are:
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
Any ideas or could anyone point me in the right direction? Thanks.
It’s a bug in the version of the Castle DynamicProxy that is merged into the moq binary (Castle.Core 2.5.0.0). It looks to affect attributes that accepts a
paramsargument. I am assumingIInputPortis decorated with such an attribute since the code is not provided?You could compile moq with the latest version of Castle.Core (3.0.0.0) (ideal).
Or (less ideal), download the latest moq release from Google Code, which includes a moq.dll version without
Castle.Coreembedded. Reference this in your project along with Castle.Core 3.0.0.0 and add the following binding redirect in your app.config. Since this is a major point upgrade I can’t vouch for it’s backward compatibility, but I tested this with your code (and anIInputPortinterface decorated with an attribute that surfaces the bug in 2.5.0.0) and it worked.