zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Higher-Order Functions and Lambdas
    dispatch_sync:As an optimization, this function invokes the block on the current thread when possible
    为什么使用dispatch_sync
    如何安全使用dispatch_sync
    dispatch_sync
    Dispatch Queues and Thread Safety
    高阶函数-参数与返回值
    In Swift, typedef is called typealias:
    偏函数应用(Partial Application)和函数柯里化(Currying)
    Centos下添加用户到用户组
  • 原文地址:https://www.cnblogs.com/yeagen/p/11706346.html
Copyright © 2011-2022 走看看