Подтвердить что ты не робот

Издевательский тип с внутренним конструктором с использованием Moq

Я пытаюсь высмеять класс из Microsoft Sync Framework. Он имеет только внутренний конструктор. Когда я попробую следующее:

var fullEnumerationContextMock = new Mock<FullEnumerationContext>();

Я получаю эту ошибку:

System.NotSupportedException: родительский не имеет конструктора по умолчанию. Конструктор по умолчанию должен быть явно определен.

Это трассировка стека:

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, Тип [] дополнительныеИнтерфейсыToProxy, Параметры ProxyGenerationOptions)     Castle.DynamicProxy.ProxyGenerator.CreateClassProxyType(Тип classToProxy, Тип [] AdditionalInterfacesToProxy, Параметры ProxyGenerationOptions)     Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Тип classToProxy, Тип [] дополнительныеИнтерфейсыToProxy, Параметры ProxyGenerationOptions, Object [] constructorArguments, IInterceptor [] перехватчики)     Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Тип classToProxy, Тип [] дополнительныеИнтерфейсыToProxy, Параметры ProxyGenerationOptions, IInterceptor [] перехватчики)     Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Тип classToProxy, Тип [] extraInterfacesToProxy, IInterceptor [] перехватчики)     Moq.Mock 1.<InitializeInstance>b__0() Moq.PexProtector.Invoke(Action action) Moq.Mock 1.InitializeInstance()

Как я могу обойти это?

4b9b3361

Ответ 1

Вы не можете высмеивать тип, не имеющий общего конструктора, потому что Moq не сможет создать экземпляр объекта такого типа. В зависимости от того, что вы пытаетесь протестировать, у вас есть несколько вариантов:

  • Если есть объект factory или какой-либо другой способ получения экземпляров FullEnumerationContext, возможно, вы можете использовать это (извините, я не знаком с инфраструктурой синхронизации)
  • Вы можете использовать частное отражение для создания экземпляра FullEnumerationContext, но тогда вы не сможете имитировать методы.
  • Вы можете ввести интерфейс и/или объект-обертку, который будет выкачать, что вызванный код может вызвать. Реализация времени выполнения будет делегировать реальный FullEnumerationContext, в то время как ваша реализация времени выполнения будет выполнять любые действия, которые вам нужны.

Ответ 2

Я не эксперт по Moq, но я думаю, вам нужно указать аргументы для конструктора. В Rhino Mocks вы должны указать их следующим образом:

var fullEnumerationContextMock = new Mock<FullEnumerationContext>(arg1, arg2);

Вероятно, это похоже на Moq.

Ответ 3

Основываясь на ответах 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);
}

Ответ 4

Собственно, вы можете. Откройте файл AssemblyInfo.cs и добавьте следующую строку в конец,

[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]