TypeLoadException при попытке издеваться над IObjectSet с помощью Moq

StackOverflow https://stackoverflow.com/questions/5008552

  •  14-11-2019
  •  | 
  •  

Вопрос

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

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, типа [], параметры ProxyGenerationOptions)
в Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithoutTarget (Type InterfaceToProxy, Type[] extraInterfacesToProxy, параметры ProxyGenerationOptions, перехватчики IInterceptor[])
в Moq.Mock1.<InitializeInstance>b__0()
at Moq.Mock
1.ИнициализироватьЭкземпляр()
в 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 как в тестовом проекте, так и в проекте, в котором находится тестируемый класс.Сборка завершается успешно без ошибок, предупреждений или сообщений (за исключением нескольких, связанных с контрактами кода...).

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

Это было полезно?

Решение

Являются ли какие-либо интерфейсы или классы, которые вы используете в своих тестах, внутренними?Вы используете что-то вроде [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

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

Другие советы

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

Мой код был примерно таким:

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

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

public class PrivateObject () {}

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

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

public IDoWork
{
    void DoWork();
}

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

class TestSomething // missing public keyword
{

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


    public IDoWork
    {
        void DoWork();
    }

}

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top