2

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()

Cortlendt
  • 2,190
  • 4
  • 29
  • 50

1 Answers1

3

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

Krzysztof Kozmic
  • 27,267
  • 12
  • 73
  • 115
  • 1
    Thanks for the feedback, but using Castle.Core.dll ver 2.5.2 and Moq.dll ver 4.0.0 - does not work. I will provide a test project to prove this later. – Cortlendt Aug 11 '11 at 14:35
  • ok. I'm pretty sure that bug was fixed, perhaps it's not v2.5.2 but trunk though... Anyway - failing test would be great. – Krzysztof Kozmic Aug 11 '11 at 21:30
  • Okay, I've hosted the test project here - [link](http://ge.tt/8KfdBl6?c) For our current project we will compile latest castle source in some time. I will post whether it will be of help. – Cortlendt Aug 12 '11 at 09:07
  • The test is using merged version of DP from Moq. The issue is most definitely fixed in Castle.Core 2.5.2 – Krzysztof Kozmic Aug 12 '11 at 10:34
  • Lastest Moq uses the exact version of Castle.Core - 2.5.0. I think you have to resort to assembly binding policy override to make it work with 2.5.2. I wonder if updating Moq to resolve this is possible: System.TypeInitializationException : The type initializer for 'Moq.Mock`1' threw an exception. ----> System.TypeInitializationException : The type initializer for 'Moq.Proxy.CastleProxyFactory' threw an exception. ----> System.IO.FileLoadException : Could not load file or assembly 'Castle.Core, Version=2.5.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc' or one of its dependencies. – Cortlendt Aug 12 '11 at 11:33
  • have you tried building moq yourself against latest Castle.Core? Alternatively try NSubstitute - it does use latest Castle.Core and I find it to be a nicer mocking framework all around. – Krzysztof Kozmic Aug 12 '11 at 12:41
  • Yes, I think this will be a good decision to do. I mean building Moq to use latest Castle.Core. – Cortlendt Aug 12 '11 at 13:37