2010-04-23 5 views
5

Ich bin komplett neu in Moq und versuche nun, einen Mock für System.Reflection.Assembly Klasse zu erstellen. Ich verwende diesen Code:Wie man ISerializable-Klassen mit Moq vortäuscht?

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

Aber wenn ich Tests laufe ich nächste Ausnahme erhalten:

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() 

Könnten Sie empfehlen mir den richtigen Weg ISerializable Klassen (wie System.Reflection.Assembly) mit Moq zu verspotten.

Vielen Dank im Voraus!

Antwort

2

Das Problem ist nicht mit ISerializable-Schnittstelle. Sie können ISerializable-Klassen verspotten.

Beachten Sie die Ausnahmemeldung:

Der Typ System.Reflection.Assembly implementiert ISerializable, scheiterte aber eine Deserialisierung zu bieten Konstruktor

Problem ist, dass Assembly nicht Deserialisierung bereitstellt Konstrukteur.

+0

Ok, danke. Aber könnten Sie vorschlagen, wie Deserialisierungskonstruktor mit Moq in diesem Fall bereitzustellen. – sam

+0

Sie können nicht - Assembly verfügt über keinen barrierefreien Konstruktor und ist daher bei Verwendung von Moq: | nicht zu entfernen –

+0

Sie müssen keinen Deserialisierungskonstruktor bereitstellen, um Assembly nachzuahmen. Sie können die interop _Assembly-Klasse überspie- len und bei Bedarf zu Assembly umwandeln. – nathanchere

1

Anstelle eines Mocks könnten Sie versuchen, eine dynamische Assembly zu erstellen und daraus zu bauen.

0

Wie bereits erläutert, besteht das Problem darin, dass Assembly keinen Deserialisierungskonstruktor freigibt. Dies bedeutet nicht, dass es nicht getan werden kann.

Eine Lösung Moq nach Ihrem Beispiel unter Verwendung wäre:

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

Beachten Sie, dass _Assembly verwenden Sie System.Runtime.InteropServices

4

System.Reflection.Assembly abstrakt verweisen müssen, können Sie so nicht Erstellen Sie eine neue Instanz davon. Sie könnten jedoch eine Testklasse erstellen, die das tut und dies mockt.

Beispiel:

 
[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 Mit RhinoMocks funktionierte der '_Assembly'-Trick nicht für mich, und ich benutzte dies. War nur auf der Suche nach einer Frage, um dieses Wissen zu teilen. – mao47

Verwandte Themen