zoukankan      html  css  js  c++  java
  • 用MOQ来Mock静态方法的 2种方法(含Moq和Fakes的配合使用)

    Moq是无法直接模拟静态方法的,解决方式有两种:

    1、需要修改正式代码,在源代码中建一个新的方法把静态方法包起来,调用的时候源代码调用时调用新方法而不是原来的静态方法。

    在测试的时候,Mock掉这个新的方法,以达到模拟的目的

    原来:

        public class FormatClass
        {
            public static string FormatDate(DateTime date)
            {
                return date.ToString("yyyyMMdd");
            }
        }
    
        public class DoClass
        {
            public void Do()
            {
                var dateString = FormatClass.FormatDate(DateTime.Now);
                Console.WriteLine(dateString);
            }
        }
    
        [TestClass]
        public class Test
        {
            [TestMethod]
            public void MyTest()
            {
                var mock = new Mock<DoClass>();
                mock.Object.Do();
            }
        }

    替换后:

       public class FormatClass
        {
            public static string FormatDate(DateTime date)
            {
                return date.ToString("yyyyMMdd");
            }
        }
    
        public class DoClass
        {
            public void Do()
            {
                var dateString = DefineFormatDate(DateTime.Now);
                Console.WriteLine(dateString);
            }
    
            //包装一个方法用于Mock
            public virtual string DefineFormatDate(DateTime date)
            {
                return FormatClass.FormatDate(date);
            }
        }
    
        [TestClass]
        public class Test
        {
            [TestMethod]
            public void MyTest()
            {
                var mock = new Mock<DoClass>();
                //Mock方法
                mock.Setup(a => a.DefineFormatDate(It.IsAny<DateTime>())).Returns("mock content");
                mock.Object.Do();
            }
        }

    2、由于Mircosoft Fakes框架可以使用Shim模拟静态方法,那么我们可以将Moq和Fakes配合起来,用Fakes模拟静态方法,其他判断还用Moq

    [TestClass]
        public class Test
        {
            [TestMethod]
            public void MyTest()
            {
                var mock = new Mock<DoClass>();
                //未Shim之前
                mock.Object.Do();
    
                using (ShimsContext.Create())
                {
                    DFYYDream.Infrastructure.Fakes.ShimPinYinConvert.ConvertToPinYinStringBoolean = (String, Boolean) =>
                    {
                        return "mock content";
                    };
    
                    //已经Shim之后
                    mock.Object.Do();
                }
    
                //moq可以正常判断
                mock.Verify(a => a.DoOther2(), Times.AtLeast(2));
            }
        }
    
        public class DoClass
        {
            public void Do()
            {
                //一个中文转拼音的静态方法
                var py = PinYinConvert.ConvertToPinYin("你好", false);
                DoOther(py);
                DoOther2();
            }
    
            public void DoOther(string py)
            {
                Console.WriteLine(py);
            }
    
            public virtual void DoOther2()
            {
            }
        }

    测试结果:

    NIHAO
    mock content

    代码里的DFYYDream.Infrastructure.Fakes命名空间,是通过右击“引用”里的程序集的名称后,选择“添加Fakes程序集”自动生成的。

     总结:

    第一种方法不需要引入Fakes,但需要修改调用处的源代码

    第二种方法不需要改把源代码,只需要在测试处模拟即可,但需要引入Fakes

  • 相关阅读:
    Linux并发与同步专题 (1)原子操作和内存屏障
    Linux并发与同步专题
    功耗案例分析:周期性底电流抬高问题分析和解决
    Android OpenGL 基础入门
    使用Codeblock搭建Windows下Objec-c学习环境
    Muduo 多线程模型对比
    NPTL 线程同步方式
    C++ 封装互斥对象
    Java 常用字符串操作总结
    Android 开发有用代码积累
  • 原文地址:https://www.cnblogs.com/yeagen/p/11714223.html
Copyright © 2011-2022 走看看