2010-04-23 1 views
5

Я полностью новичок в Moq и теперь пытаюсь создать макет для System.Reflection.Assembly класс. Я использую этот код:Как насмехаться с классами ISerializable с Moq?

var mockAssembly = new Mock<Assembly>(); 
mockAssembly.Setup(x => x.GetTypes()).Returns(new Type[] { 
    typeof(Type1), 
    typeof(Type2) 
}); 

Но когда я бегу тестов я получаю следующее исключение:

System.ArgumentException : The type System.Reflection.Assembly 
implements ISerializable, but failed to provide a deserialization 
constructor 
Stack Trace: 
    at 
Castle.DynamicProxy.Generators.BaseProxyGenerator.VerifyIfBaseImplementsGet­ObjectData(Type 
baseType) 
    at 
Castle.DynamicProxy.Generators.ClassProxyGenerator.GenerateCode(Type[] 
interfaces, ProxyGenerationOptions options) 
    at Castle.DynamicProxy.DefaultProxyBuilder.CreateClassProxy(Type 
classToProxy, Type[] additionalInterfacesToProxy, 
ProxyGenerationOptions options) 
    at Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type 
classToProxy, Type[] additionalInterfacesToProxy, 
ProxyGenerationOptions options, Object[] constructorArguments, 
IInterceptor[] interceptors) 
    at Moq.Proxy.CastleProxyFactory.CreateProxy[T](ICallInterceptor 
interceptor, Type[] interfaces, Object[] arguments) 
    at Moq.Mock`1.<InitializeInstance>b__0() 
    at Moq.PexProtector.Invoke(Action action) 
    at Moq.Mock`1.InitializeInstance() 
    at Moq.Mock`1.OnGetObject() 
    at Moq.Mock`1.get_Object() 

Не могли бы вы рекомендовать мне правильный путь, чтобы поиздеваться ISerializable классы (как System.Reflection.Assembly) с Moq.

Заранее спасибо!

ответ

2

Проблема не в интерфейсе ISerializable. Вы можете mock ISerializable classes.

Обратите внимание на сообщение об исключении:

Тип System.Reflection.Assembly реализует ISerializable, но не , чтобы обеспечить десериализации конструктор

Проблема заключается в том, что Ассамблея не обеспечивает десериализации конструктор.

+0

Хорошо, спасибо. Но вы могли бы предложить, как создать конструктор десериализации, используя Moq в этом случае. – sam

+0

вы не можете - сборка не имеет доступного конструктора, и поэтому она не может быть использована при использовании Moq: | –

+0

Вам не нужно предоставлять конструктор десериализации, чтобы издеваться над сборкой. Вы можете издеваться над классом interop _Assembly и отбрасывать на сборку, когда это необходимо. – nathanchere

1

Вместо макета вы можете попробовать создать динамическую сборку и построить из нее.

var appDomain = AppDomain.CurrentDomain; 
var assembly = appDomain.DefineDynamicAssembly(new AssemblyName("Test"), AssemblyBuilderAccess.ReflectionOnly); 
0

Как уже объяснялось, проблема заключается в том, что Assembly не подвергает конструктору десериализации. Это не значит, что это невозможно сделать.

Раствор с помощью Moq в соответствии с вашим примером будет:

var mock = new Mock<_Assembly>(); 
    result.Setup(/* do whatever here as usual*/); 

Обратите внимание, что для использования _Assembly вам нужно будет ссылаться System.Runtime.InteropServices

4

System.Reflection.Assembly является абстрактным, так что вы не можете создайте новый экземпляр. Тем не менее, вы можете создать тестовый класс, который будет выполнять и выполнить Mock.

Пример:

 
[TestMethod] 
public void TestSomethingThatNeedsAMockAssembly() 
{ 
    string title = "title";
var mockAssembly = new Mock();
mockAssembly.Setup(a => a.GetCustomAttributes(It.Is(s => s == Type.GetType("System.Reflection.AssemblyTitleAttribute")), It.IsAny())).Returns(new System.Attribute[] { new AssemblyTitleAttribute(title) });

var c = new ClassThatTakesAssemblyAndParsesIt(mockAssembly.Object); Assert.IsTrue(c.AssemblyTitle == title); //etc } public class TestAssembly : Assembly { public TestAssembly() { //could probably do something interesting here } }

+1

+1 Используя RhinoMocks, трюк '_Assembly' не работал для меня, и я в конечном итоге использовал это. Просто искал вопрос, чтобы поделиться этими знаниями. – mao47