JobaDiniz
JobaDiniz

Reputation: 1003

Moq a property of concrete class with another moq

I'm trying to create a mock of a concrete class and mock one of its properties with another mock.

public class MyClass
{
  public virtual IAdapter Adapter {get; internal set;}
}

Testing...

var adapter = new Mock<IAdapter>();
adapter.Setup(a => a.WaitForDigit()).Returns(1);
var myClass = new Mock<MyClass>();
myClass.Setup(c => c.Adapter).Returns(adapter.Object); //throws exception

It throws the following exception: System.ArgumentException: Constant does not match the defined type

How can I fix that?

Edit:

I've changed the design and even then it's still throwing the same exception

public class MyClass
{
  public virtual IAdapter Adapter {get;set;}
  public MyClass(IAdapter adapter)
  {
    Adapter = adapter;
  }
}

var adapter = new Mock<IAdapter>();
adapter.Setup(a => a.WaitForDigit()).Returns(1);
var myClass = new MyClass(adapter.Object); //throws exception

System.ArgumentException: Constant does not match the defined type.
Result StackTrace:  
at System.Reflection.Emit.TypeBuilder.SetConstantValue(ModuleBuilder module, Int32 tk, Type destType, Object value)
   at System.Reflection.Emit.ParameterBuilder.SetConstant(Object defaultValue)
   at Castle.DynamicProxy.Generators.Emitters.MethodEmitter.DefineParameters(ParameterInfo[] parameters)
   at Castle.DynamicProxy.Generators.Emitters.MethodEmitter..ctor(AbstractTypeEmitter owner, String name, MethodAttributes attributes, MethodInfo methodToUseAsATemplate)
   at Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.CreateMethod(String name, MethodAttributes attributes, MethodInfo methodToUseAsATemplate)
   at Castle.DynamicProxy.Generators.MethodGenerator.Generate(ClassEmitter class, ProxyGenerationOptions options, INamingScope namingScope)
   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.ClassProxyGenerator.GenerateType(String name, Type[] interfaces, INamingScope namingScope)
   at Castle.DynamicProxy.Generators.ClassProxyGenerator.<>c__DisplayClass1.<GenerateCode>b__0(String n, INamingScope s)
   at Castle.DynamicProxy.Generators.BaseProxyGenerator.ObtainProxyType(CacheKey cacheKey, Func`3 factory)
   at Castle.DynamicProxy.Generators.ClassProxyGenerator.GenerateCode(Type[] interfaces, ProxyGenerationOptions options)
   at Castle.DynamicProxy.DefaultProxyBuilder.CreateClassProxyType(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options)
   at Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, Object[] constructorArguments, IInterceptor[] interceptors)
   at Moq.Proxy.CastleProxyFactory.CreateProxy(Type mockType, ICallInterceptor interceptor, Type[] interfaces, Object[] arguments)
   at Moq.Mock`1.<InitializeInstance>b__24_0()
   at Moq.PexProtector.Invoke(Action action)
   at Moq.Mock`1.InitializeInstance()
   at Moq.Mock`1.OnGetObject()
   at Moq.Mock.GetObject()
   at Moq.Mock.get_Object()
   at Moq.Mock`1.get_Object()

Upvotes: 4

Views: 1167

Answers (2)

Fran
Fran

Reputation: 6520

This looks like a design issue to me. If you have a dependency on another class then that dependency shouldn't be public. See here

Should injected dependencies be publicly accessible or private?

Once that dependency is wrapped and there is no external access, there is no reason to have to moq this dependency. Your moq'ed methods for MyClass should be sufficient.

Upvotes: 2

JobaDiniz
JobaDiniz

Reputation: 1003

Turns out this has nothing to do with Moq. It is a Castle.Core bug as reported here.

To solve this, I've installed Castle.Core v4.0 beta package.

Upvotes: 2

Related Questions