用MOQ来Mock静态方法的 2种方法

人走茶凉 提交于 2019-12-01 19:23:20

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

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

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!