Search code examples
c#unit-testingmoqmicrosoft-sync-framework

Mocking a type with an internal constructor using Moq


I'm trying to mock a class from the Microsoft Sync Framework. It only has an internal constructor. When I try the following:

var fullEnumerationContextMock = new Mock<FullEnumerationContext>();

I get this error:

System.NotSupportedException: Parent does not have a default constructor. The default constructor must be explicitly defined.

This is the stack trace:

System.Reflection.Emit.TypeBuilder.DefineDefaultConstructorNoLock(MethodAttributes attributes) System.Reflection.Emit.TypeBuilder.DefineDefaultConstructor(MethodAttributes attributes) System.Reflection.Emit.TypeBuilder.CreateTypeNoLock() System.Reflection.Emit.TypeBuilder.CreateType() Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.BuildType() Castle.DynamicProxy.Generators.ClassProxyGenerator.GenerateCode(Type[] interfaces, ProxyGenerationOptions options) Castle.DynamicProxy.DefaultProxyBuilder.CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options) Castle.DynamicProxy.ProxyGenerator.CreateClassProxyType(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options) Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, Object[] constructorArguments, IInterceptor[] interceptors) Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, IInterceptor[] interceptors) Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, IInterceptor[] interceptors) Moq.Mock1.<InitializeInstance>b__0() Moq.PexProtector.Invoke(Action action) Moq.Mock1.InitializeInstance()

How can I work round this?


Solution

  • You cannot mock a type that does not have a public constructor because Moq will not be able to instantiate an object of that type. Depending on what you are trying to test, you have a few options:

    1. If there's a factory object or some other way of obtaining instances of FullEnumerationContext perhaps you can use that (sorry, I'm not familiar with the sync framework)
    2. You could use private reflection to instantiate a FullEnumerationContext, but then you would not be able to mock methods on it.
    3. You could introduce an interface and/or wrapper object that's mockable that the code under test could invoke. The runtime implementation would delegate to the real FullEnumerationContext, while your test-time implementation would perform whatever action you need.