Search code examples
moqaoprhino-mockscastlecastle-dynamicproxy

Moq + Castle Dynamic Proxy - exception mocking nested generic interfaces


I'm receiving an argument exception from Castle Dynamic Proxy, while using Moq to create a mock of object that is implementing a nested generic interface with generic method that has an interface constraint.

The exception is: System.ArgumentException : Cannot set parent to an interface.

Happens while accessing Object property of the mock directly after the mock creation. (Call stack is at the bottom for the sake of readability)

The code is simple and self-describing:

    public interface A<T>
    {
        void Method<Z>() where Z : T; 
    }

    public interface B
    {
    }

    [Test]
    public void MockNestedGenericInterfaceTest()
    {
        Mock<A<B>> mock = new Mock<A<B>>();
        var o = mock.Object; //argument exception here
    }

Test does not generate an exception if where Z : T clause is removed.

I did some research and found a ticket here. I'm using latest versions of Moq and Castle.

Is there a workaround for this problem? The only way I see it working is a manual mock implementation. Rhino mocks did not work for me either.

Thank you.

Call stack:

at System.Reflection.Emit.TypeBuilder.SetParent(Type parent)

at Castle.DynamicProxy.Generators.Emitters.GenericUtil.CopyGenericArguments(MethodInfo methodToCopyGenericsFrom, Dictionary2 name2GenericType, ApplyGenArgs genericParameterGenerator) at Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.CopyGenericParametersFromMethod(MethodInfo methodToCopyGenericsFrom) at Castle.DynamicProxy.Generators.InvocationTypeGenerator.Generate(ClassEmitter class, ProxyGenerationOptions options, INamingScope namingScope) at Castle.DynamicProxy.Contributors.InterfaceProxyWithoutTargetContributor.GetInvocationType(MetaMethod method, ClassEmitter emitter, ProxyGenerationOptions options) at Castle.DynamicProxy.Contributors.InterfaceProxyWithoutTargetContributor.GetMethodGenerator(MetaMethod method, ClassEmitter class, ProxyGenerationOptions options, OverrideMethodDelegate overrideMethod) at Castle.DynamicProxy.Contributors.CompositeTypeContributor.ImplementMethod(MetaMethod method, ClassEmitter class, ProxyGenerationOptions options, OverrideMethodDelegate overrideMethod) 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.Mock1.b__0() at Moq.Mock1.InitializeInstance() at Moq.Mock1.OnGetObject() at Moq.Mock`1.get_Object()


Solution

  • This bug was fixed in last version of DynamicProxy. Make sure you're using latest version of Moq