C# 最小起重量(Moq):具有另一最小起重量(Moq)的混凝土类的性质

C# 最小起重量(Moq):具有另一最小起重量(Moq)的混凝土类的性质,c#,unit-testing,moq,C#,Unit Testing,Moq,我试图创建一个具体类的mock,并用另一个mock来模拟它的一个属性 public class MyClass { public virtual IAdapter Adapter {get; internal set;} } 测试 var adapter = new Mock<IAdapter>(); adapter.Setup(a => a.WaitForDigit()).Returns(1); var myClass = new Mock<MyClass>

我试图创建一个具体类的mock,并用另一个mock来模拟它的一个属性

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

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
var adapter=new Mock();
Setup(a=>a.WaitForDigit())。返回(1);
var myClass=newmock();
Setup(c=>c.Adapter).Returns(Adapter.Object)//抛出异常
它引发以下异常: System.ArgumentException:常量与定义的类型不匹配

我怎样才能解决这个问题

编辑:

我已经改变了设计,即使如此,它仍然抛出相同的异常

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()
公共类MyClass
{
公共虚拟IAdapter适配器{get;set;}
公共MyClass(IAdapter适配器)
{
适配器=适配器;
}
}
var adapter=newmock();
Setup(a=>a.WaitForDigit())。返回(1);
var myClass=新的myClass(adapter.Object)//抛出异常
System.ArgumentException:常量与定义的类型不匹配。
结果跟踪:
位于System.Reflection.Emit.TypeBuilder.SetConstantValue(ModuleBuilder模块,Int32 tk,类型destType,对象值)
位于System.Reflection.Emit.ParameterBuilder.SetConstant(对象默认值)
在Castle.DynamicProxy.Generators.Emitters.MethodEmitter.DefineParameters(ParameterInfo[]参数)中
位于Castle.DynamicProxy.Generators.Emitters.MethodEmitter..ctor(AbstractTypeEmitter所有者、字符串名称、MethodAttributes属性、MethodInfo MethodToEasateTemplate)
位于Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.CreateMethod(字符串名称、MethodAttributes属性、MethodInfo methodToUseAsATemplate)
在Castle.DynamicProxy.Generators.MethodGenerator.Generate(ClassEmitter类,ProxyGenerationOptions选项,InMingScope命名范围)
位于Castle.DynamicProxy.Contributors.CompositeTypeContributor.ImplementMethod(元方法、类发射器类、ProxyGenerationOptions、OverrideMethodedElegate overrideMethod)
在Castle.DynamicProxy.Contributors.CompositeTypeContributor.Generate(ClassEmitter类,ProxyGenerationOptions选项)
在Castle.DynamicProxy.Generators.ClassProxyGenerator.GenerateType(字符串名称,类型[]接口,InMingScope namingScope)
在Castle.DynamicProxy.Generators.ClassProxyGenerator.c\u显示class1.b\u 0(字符串n,INamingScope s)
在Castle.DynamicProxy.Generators.BaseProxyGenerator.ActainProxyType(CacheKey CacheKey,Func`3工厂)
位于Castle.DynamicProxy.Generators.ClassProxyGenerator.GenerateCode(类型[]接口,ProxyGenerationOptions)
在Castle.DynamicProxy.DefaultProxyBuilder.CreateClassProxyType(类型classToProxy,类型[]additionalInterfacesToProxy,ProxyGenerationOptions)
位于Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(类型classToProxy,类型[]additionalInterfacesToProxy,类型[]additionalInterfacesToProxy,ProxyGenerationOptions,对象[]构造函数参数,IInterceptor[]拦截器)
在Moq.Proxy.CastleProxyFactory.CreateProxy(类型mockType、iCalInterceptor拦截器、类型[]接口、对象[]参数)
最低起订量模拟'1.b_uu24_u0()
在Moq.PexProtector.Invoke(操作)
在Moq.Mock`1.InitializeInstance()
最小起订量模拟'1.OnGetObject()
在Moq.Mock.GetObject()处
在Moq.Mock.get_Object()处
在Moq.Mock`1.get_Object()

对我来说,这似乎是一个设计问题。如果您对另一个类有依赖关系,那么该依赖关系不应该是公共的。看这里


一旦该依赖项被包装,并且没有外部访问,就没有理由必须删除该依赖项。MyClass的最小起订量方法应该足够了。

结果表明,这与最小起订量无关。据报道,这是一个
Castle.Core
bug


为了解决这个问题,我安装了
Castle.Core
v4.0测试包。

MyClass与测试在同一个程序集中吗?如果没有,则无法访问Apapter
internal
setter,这可能会混淆Moq。如果@stuartd对
internal
setter混淆Moq的说法是正确的,
InternalsVisibleToAttribute
()可能会帮助您克服此问题。
MyClass
与测试不在同一程序集中。我已将
InternalsVisibleToAttribute(“MyAssembly.Tests”)
应用于MyClass程序集,但错误相同。请尝试使用
MyClass
使程序集通过
InternalsVisibleToAttribute
向Moq程序集公开其内部,因为Moq将覆盖这个类。我认为这与此有关:因为
IAdapter
具有可为空参数的方法。你完全正确。但是我现在可以改变设计,我想知道为什么moq会抛出这个错误。我已经改变了一点设计,异常仍然存在。