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

Исключение TypeLoadException при попытке подделать IObjectSet с помощью Moq

У меня есть следующий код установки:

MockOf<IObjectSet<Dummy>>().Setup(c => c.AddObject(dummy)).Verifiable();
MockOf<IObjectContextWrapper>().Setup(c => c.GetObjectSet<Dummy>()).Returns(MockOf<IObjectSet<Dummy>>().Object);

где Dummy - пустое определение класса, а Dummy - Dummy. MockOf<T>() - это функция управления макетами в базовом классе, которая в основном гарантирует, что каждый раз, когда он вызывает тип, он возвращает тот же макет.

Тест, содержащий этот код установки, сбой TypeLoadException и следующее сообщение:

System.TypeLoadException: введите 'IObjectSet`1Proxy389e220f10aa4d9281d0b9e136edc1d4' из сборки 'DynamicProxyGenAssembly2, Version = 0.0.0.0, Culture = neutral, PublicKeyToken = a621a9e7e5c32e69' пытается реализовать недоступный интерфейс.

в System.Reflection.Emit.TypeBuilder.TermCreateClass(модуль RuntimeModule, Int32 tk, тип ObjectHandleOnStack)
в System.Reflection.Emit.TypeBuilder.CreateTypeNoLock()
в System.Reflection.Emit.TypeBuilder.CreateType()
в Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.BuildType()
в Castle.DynamicProxy.Generators.InterfaceProxyWithTargetGenerator.GenerateCode(Тип proxyTargetType, Type [] интерфейсы, параметры ProxyGenerationOptions)
в Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithoutTarget(тип interfaceToProxy, Type [] дополнительныеИнтерфейсыToProxy, опции ProxyGenerationOptions, перехватчики IInterceptor [])
в Moq.Mock 1.<InitializeInstance>b__0()
at Moq.Mock
1.InitializeInstance()
в Moq.Mock`1.get_Object()
в OddEnds.Tests.Data.EntityFramework.RepositoryTest.Delete_DeletesObjectFromObjectSet() в RepositoryTest.cs: строка 43

Я импортировал System.Data.Objects и ссылался как на System.Data.Entity.dll, так и на Microsoft.Data.Entity.CTP.dll как в тестовом проекте, так и в проекте, в котором находится тестируемый класс. Сборка успешно завершена без ошибок, предупреждений или сообщений (кроме нескольких связанных с кодовыми контрактами...)

Как это исправить?

4b9b3361

Ответ 1

Являются ли какие-либо интерфейсы или классы, которые вы используете во внутренних тестах? Используете ли вы что-то вроде [assembly: InternalsVisibleTo("YourTestAssembly")] для того, чтобы получить вещи для компиляции?

Если да, то вам также необходимо добавить один для DynamicProxyGenAssembly2 для того, чтобы Moq динамически генерировать прокси для классов.

//goes in the AssemblyInfo.cs where the internal interfaces / classes are defined
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]  

Вот ссылка на тему

http://sonofpirate.blogspot.com/2009/09/my-first-foray-into-unit-testing-with.html

Я надеюсь, что это поможет

Ответ 2

Я обнаружил, что в моем случае я создал экземпляр класса Dummy, который будет использоваться в моем unit test, который оказался закрытым (поскольку я действительно не хотел делиться тестовым объектом снаружи).

Мой код был в следующих строках:

var mockMonitor = new Mock<ICacheMonitor<int, PrivateObject>>();

где PrivateObject был определением частного класса в моем TestClass. Исправление в моем случае, следовательно, должно гарантировать, что любой из типов в вашем конструкторе Mock является общедоступным.

public class PrivateObject () {}

(Очевидно, что я бы не назвал свой публичный объект PrivateObject либо...)

Ответ 3

Я споткнулся о другой случай, который я не мог понять поначалу. Я работал над прокси для интерфейса, созданного внутри моего unit test...

public IDoWork
{
    void DoWork();
}

Мне потребовалось время, чтобы понять, что проблема связана не с этим интерфейсом, а скорее с тем, что сам unit test не был общедоступным:

class TestSomething // missing public keyword
{

// .. some test which tries to create a mock of the interface


    public IDoWork
    {
        void DoWork();
    }

}

Итак, хотя IDoWork говорит, что он общедоступен, это действительно не так, поскольку он заключен в закрытый класс.

Надеюсь, это поможет кому-то.