使用Moq

模拟具有内部构造函数的类型 我正在尝试从Microsoft Sync Framework模拟一个类。它只有一个内部构造函数。当我尝试以下内容时:
var fullEnumerationContextMock = new Mock<FullEnumerationContext>();
我收到此错误:   System.NotSupportedException:Parent   没有默认构造函数。   默认构造函数必须是   明确定义。 这是堆栈跟踪:   System.Reflection.Emit.TypeBuilder.DefineDefaultConstructorNoLock(MethodAttributes   属性)       System.Reflection.Emit.TypeBuilder.DefineDefaultConstructor(MethodAttributes   属性)       System.Reflection.Emit.TypeBuilder.CreateTypeNoLock()       System.Reflection.Emit.TypeBuilder.CreateType()       Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.BuildType()       Castle.DynamicProxy.Generators.ClassProxyGenerator.GenerateCode(类型[]   接口,ProxyGenerationOptions选项)       Castle.DynamicProxy.DefaultProxyBuilder.CreateClassProxy(类型classToProxy,Type [] additionalInterfacesToProxy,   ProxyGenerationOptions选项)       Castle.DynamicProxy.ProxyGenerator.CreateClassProxyType(Type classToProxy,Type [] additionalInterfacesToProxy,   ProxyGenerationOptions选项)       Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(类型classToProxy,Type [] additionalInterfacesToProxy,   ProxyGenerationOptions选项,Object [] constructorArguments,   IInterceptor []拦截器)       Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(类型classToProxy,Type [] additionalInterfacesToProxy,   ProxyGenerationOptions选项,IInterceptor []拦截器)       Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(类型classToProxy,Type [] additionalInterfacesToProxy,IInterceptor []   拦截器)       Moq.Mock
1.<InitializeInstance>b__0()
      Moq.PexProtector.Invoke(Action action)
      Moq.Mock
1.InitializeInstance() 我该如何解决这个问题呢?     
已邀请:
您不能模拟没有公共构造函数的类型,因为Moq将无法实例化该类型的对象。根据您要测试的内容,您有以下几种选择: 如果有工厂对象或其他获取FullEnumerationContext实例的方法,也许你可以使用它(抱歉,我不熟悉同步框架) 您可以使用私有反射来实例化FullEnumerationContext,但是您将无法在其上模拟方法。 您可以引入一个接口和/或包装器对象,它可以模拟被测试的代码可以调用。运行时实现将委托给真正的FullEnumerationContext,而您的测试时实现将执行您需要的任何操作。     
我不是Moq的专家,但我认为你需要指定构造函数的参数。在Rhino Mocks中,您可以像这样指定它们:
var fullEnumerationContextMock = new Mock<FullEnumerationContext>(arg1, arg2);
它在Moq中可能类似。     
基于marcind的答案,我创建了一个界面(
IFullEnumerationContext
),我嘲笑然后我有两个重载我试图测试的方法,一个需要
FullEnumerationContext
而另一个需要
IFullEnumerationContext
。它感觉不太好,但确实有效。任何更好的建议或改进都将受到欢迎。
public override void EnumerateItems(FullEnumerationContext context)
{
    List<ItemFieldDictionary> listItemFieldDictionary = EnumerateItemsCommon();
    context.ReportItems(listItemFieldDictionary);
}

public void EnumerateItems(IFullEnumerationContext context)
{
    List<ItemFieldDictionary> listItemFieldDictionary = EnumerateItemsCommon();
    context.ReportItems(listItemFieldDictionary);
}
    
其实你可以。打开AssemblyInfo.cs文件并在结尾添加以下行,
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
    

要回复问题请先登录注册