2016-12-06 9 views
4

Я пытаюсь создать издевательство над конкретным классом и издеваться над одним из его свойств с помощью другого макета.Moq свойство конкретного класса с другим moq

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 

Он бросает следующее исключение: System.ArgumentException: Константа не соответствует определенному типу

Как я могу исправить это?

Edit:

Я изменил дизайн и даже тогда он по-прежнему бросать же исключение

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

Является ли MyClass той же сборкой, что и тест? Если нет, то установочный параметр «Внутренний» Apapter не будет доступен, что может ввести в заблуждение Moq. – stuartd

+0

Если @stuartd прав насчет «внутреннего» сеттера, запутанного Moq, «InternalsVisibleToAttribute» (https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute(v=vs.110) .aspx) может помочь вам преодолеть эту проблему. – wablab

+0

'MyClass' находится не в той же сборке, что и в тесте. Я применил 'InternalsVisibleToAttribute (« MyAssembly.Tests »)' для сборки MyClass, но ошибка такая же. – JobaDiniz

ответ

2

Это выглядит как дизайн вопрос для меня. Если у вас есть зависимость от другого класса, тогда эта зависимость не должна быть общедоступной. Смотрите здесь

Should injected dependencies be publicly accessible or private?

После того, как эта зависимость обернута и нет никакого внешнего доступа, то нет никаких оснований должны MOq этой зависимости. Ваши методы moq'ed для MyClass должны быть достаточными.

+0

Ты совершенно прав. Но я могу изменить дизайн прямо сейчас, и я хотел знать, почему moq выбрасывает эту ошибку. – JobaDiniz

+0

Я немного изменил дизайн, и исключение сохраняется. – JobaDiniz

0

Оказывается, это не имеет никакого отношения к Moq. Это ошибка Castle.Core, как сообщается here.

Чтобы решить эту проблему, я установил Castle.Core v4.0 beta package.