【问题标题】:How to mock ISerializable classes with Moq?如何使用 Moq 模拟 ISerializable 类?
【发布时间】:2011-02-11 09:06:51
【问题描述】:

我对 Moq 完全陌生,现在正在尝试为 System.Reflection.Assembly 班级。我正在使用此代码:

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)与最小起订量。

提前致谢!

【问题讨论】:

    标签: .net moq serializable


    【解决方案1】:

    System.Reflection.Assembly 是抽象的,因此您不能创建它的新实例。但是,您可以创建一个测试类并模拟它。

    例子:

    [测试方法] 公共无效 TestSomethingThatNeedsAMockAssembly() { 字符串标题 = "标题";
    var mockAssembly = new Mock();
    mockAssembly.Setup(a => a.GetCustomAttributes(It.Is(s => s == Type.GetType("System.Reflection.AssemblyTitleAttribute")), It.IsAny())).Returns(new System.Attribute[ ] { 新的 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 使用 RhinoMocks,_Assembly 技巧对我不起作用,我最终使用了它。只是在寻找一个问题来分享这些知识。
    【解决方案2】:

    问题不在于 ISerializable 接口。您可以模拟 ISerializable 类。

    注意异常信息:

    System.Reflection.Assembly 类型 实现 ISerializable,但失败 提供反序列化 构造函数

    问题是,Assembly 不提供反序列化构造函数。

    【讨论】:

    • 好的,谢谢。但是您能否建议在这种情况下如何使用 Moq 提供反序列化构造函数。
    • 你不能 - 程序集没有任何可访问的构造函数,因此在使用 Moq 时它是不可模拟的:|
    • 您不需要提供反序列化构造函数来模拟 Assembly。您可以模拟互操作 _Assembly 类并在需要时转换为 Assembly。
    【解决方案3】:

    如前所述,问题在于 Assembly 没有公开反序列化构造函数。但这并不意味着它不能完成。

    根据您的示例使用 Moq 的解决方案是:

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

    请注意,要使用_Assembly,您需要引用System.Runtime.InteropServices

    【讨论】:

      【解决方案4】:

      您可以尝试创建动态程序集并从中构建,而不是模拟。

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

      【讨论】:

        【解决方案5】:

        我只需要验证嵌入式资源是否正常工作;这适用于我的情况:

            public class MockableAssembly : Assembly { }
        
            [TestClass]
            public class ApplicationSetupTests
            {
                [TestMethod]
                public void ApplyAsposeLicense_Success()
                {
                    var mockAssembly = new Mock<MockableAssembly>();
                    mockAssembly.Setup(a => a.GetManifestResourceStream(It.IsAny<string>())).Returns(mockedData);
        
                    MethodIAmTesting(mockAssembly.Object);
        
                    mockAssembly.Verify(a => a.GetManifestResourceStream("myString"), Times.Once);
                }
        

        【讨论】:

        • 我所需要的只是一个可以调用 .GetTypes() 且具有可预测类型的程序集,这就是为我解决的问题。像这个答案一样,创建一个像MockableAssembly 这样的继承类。模拟你需要的所有函数,然后你可以将它转换回Assembly 并再次处理它
        猜你喜欢
        • 2015-04-04
        • 1970-01-01
        • 1970-01-01
        • 2019-01-08
        • 2018-03-29
        • 2012-06-16
        • 1970-01-01
        • 2012-03-18
        • 2010-10-19
        相关资源
        最近更新 更多