MOQ中CallBase的作用

当使用Moq来Mock一个具体的类,类里的方法为virtual时,Moq会将当前类,所有的virtual方法默认重写成空实现。

如果我们想要访问真实的代码,有两种方法

1、在创建Mock时,设置CallBack为True:则当前类里所有的方法全访问真实代码

var mock = new Mock<ChildClass>() { CallBase = true};
mock.Object.ChildDo();

2、只想单个访问真实代码,可以Setup此方法后,调用.CallBase()方法

mock.Setup(a => a.ChildDo()).CallBase();

-------------------------------------

当我们要监控父类里的虚方法时,这里有一个很恶心的地方:

如果子类里使用base.BaseDo()来调用父类的功能,父类的BaseDo方法无法被重写,也无法监控。

如果子类里使用this.BaseDo()或直接写BaseDo()来调用父类的功能,则父类的BaseDo方法会被重写,也可以监控。

    public class BaseClass
    {
        public virtual void BaseDo()
        {
            throw new Exception("BaseDo");//检测时请屏蔽
        }
    }

    public class ChildClass : BaseClass
    {
        public void ChildDo()
        {
            base.BaseDo();//不重写BaseDo方法,会throw,不能通过Verify检测
            //this.BaseDo();//会重写BaseDo方法,不会throw,能通过Verify检测
        }
    }

    [TestClass]
    public class Test
    {
        [TestMethod]
        public void Testing()
        {
            var mock = new Mock<ChildClass>();
            mock.Object.ChildDo();
            mock.Verify(a => a.BaseDo(), Times.Once);
        }
    }

我估计这么设计是因为是想严格判断是base里的还是this里的方法,这么一想还挺有道理,比如:

    public class BaseClass
    {
        public virtual bool BaseDo()
        {
            return false;
        }
    }

    public class ChildClass : BaseClass
    {
        public override bool BaseDo()
        {
            return true;
        }

        public bool ChildDo()
        {
            return base.BaseDo();//不会监控
            //return this.BaseDo();//会监控
        }
    }

    [TestClass]
    public class Test
    {
        [TestMethod]
        public void Testing()
        {
            var mock = new Mock<ChildClass>();
            var result = mock.Object.ChildDo();
            mock.Verify(a => a.BaseDo(), Times.Once);
        }
    }

在这个例子里,base.BaseDo()和this.BaseDo()就是两个不同的方法,这时Moq判断的逻辑就更加清晰了

原则上,如果我们在代码里严格指定调用的是父类的方法(base.xxx()),那么Moq就不会去虚拟和监控父类的方法

-----------------------

参考资料:

https://www.cnblogs.com/haogj/archive/2011/07/22/2113496.html

https://www.cnblogs.com/darrenji/p/3869602.html

原文地址:https://www.cnblogs.com/yeagen/p/11706346.html