TypeLoadException при попытке смоделировать IObjectSet с Moq - PullRequest
17 голосов
/ 15 февраля 2011

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

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, Версия = 0.0.0.0, Культура = нейтральная, PublicKeyToken = a621a9e7eeeeeceeeeee)

в System.Reflection.Emit.TypeBuilder.TermCreateClass (модуль RuntimeModule, Int32 tk, тип ObjectHandleOnStack)
в System.Reflection.Emit.TypeBuilder.CreateTypeNoLock ()
в System.Reflection.Emit.TypeBuilder.CreateType ()
at Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.BuildType ()
at Castle.DynamicProxy.Generators.InterfaceProxyWithTargetGenerator.GenerateCode (Тип интерфейсы proxyTargetType, Тип [], параметры ProxyGenerationOptions)
в Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithoutTarget (Тип interfaceToProxy, Тип [] AdditionalInterfacesToProxy, Опции ProxyGenerationOptions, Перехватчики IInterceptor [])
в Moq.Mock 1.<InitializeInstance>b__0()<br> 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 как в тестовом проекте, так и в проекте, где находится тестируемый класс. Сборка завершается успешно без ошибок, предупреждений или сообщений (кроме нескольких, связанных с контрактами кода ...)

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

Ответы [ 3 ]

16 голосов
/ 30 июля 2011

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

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

12 голосов
/ 08 ноября 2012

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

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

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

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

public class PrivateObject () {}

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

0 голосов
/ 05 июня 2017

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

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 говорит, что он публичный, на самом деле это не так, поскольку он заключен в закрытый класс.

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

...