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

  • 相关阅读:
    jvm误区--动态对象年龄判定
    jmeter入门实例
    七牛云的文件上传和下载
    layer.prompt添加多个输入框
    zero copy图解
    java枚举的线程安全及序列化
    java单例模式
    ubuntu16.04 python3.5 opencv的安装与卸载(转载)
    独家git clone 加速方法
    apt get update无法正常使用解决方案(转载)
  • 原文地址:https://www.cnblogs.com/yeagen/p/11706346.html
Copyright © 2011-2022 走看看