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
MOQ中CallBase的作用的更多相关文章
- web.xml中load-on-startup的作用
如下一段配置,熟悉DWR的再熟悉不过了:<servlet> <servlet-name>dwr-invoker</servlet-name> <ser ...
- C#中构造函数的作用
C#中构造函数的作用 共同点: 都是实例化对象,初始化数据的 默认构造是说所有的类都从祖先object那继承了空参的构造方法,你不写与写空参构造都存在,而有参数的构造一般是自己写的,写就有不写就没有, ...
- MySQL数据库中delimiter的作用概述
以下的文章主要是向大家描述的是MySQL数据库中delimiter的作用是什么?我们一般都认为这个命令和存储过程关系不大,到底是不是这样的呢?以下的文章将会给你相关的知识,望你会有所收获. 其实就是告 ...
- js中getBoundingClientRect的作用及兼容方案
js中getBoundingClientRect的作用及兼容方案 1.getBoundingClientRect的作用 getBoundingClientRect用于获取某个html元素相对于视窗的位 ...
- Linq中关键字的作用及用法
Linq中关键字的作用及用法 1.All:确定序列中的所有元素是否都满足条件.如果源序列中的每个元素都通过指定谓词中的测试,或者序列为空,则为 true:否则为 false. Demo: 此示例使用 ...
- JAVA中protected的作用
JAVA中protected的作用 1.public:public表明该数据成员.成员函数是对所有用户开放的,所有用户都可以直接进行调用 2.private:private表示私有,私有的意思就是 ...
- url中#号的作用
url中#号的作用就是本页面位置跳转 比如这个url地址:http://www.aaaaa.com/index.html?ad=34&m=c#red red就是index.html页面的依哥位 ...
- Java中hashCode的作用
转 http://blog.csdn.net/fenglibing/article/details/8905007 Java中hashCode的作用 2013-05-09 13:54 64351人阅 ...
- struts2 中 Actionsupport 的作用
struts2 中 Actionsupport 的作用 Action 跟 Actionsupport 的区别 当我们在写action的时候,可以实现Action接口,也可以继承Actionsu ...
随机推荐
- bootstrap Table 的使用方法
然后添加css 找到bootstrap-table.min.css 添加进去 再添加JS Js添加时 按照顺序添加 然后初始化bootstrap-table <script type=&qu ...
- 011_Python3 集合
集合(set)是一个无序的不重复元素序列. 可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典. 创 ...
- 在qml中使用model给委托对象MapPolylIne的path属性赋值。
遇到两个崩溃的问题. 1.A线程中给赋值了变量 listA, 线程B中使用函数Add(QList<GeoPath> &list),由于在其函数中调用了list.at(index), ...
- nodejs+supertest+mocha 接口测试环境搭建
系统接口自动化测试 该框架用于对系统的接口自动化测试(nodejs+supertest+mocha)Homebrew 安装: ruby -e "$(curl -fsSL {+}https:/ ...
- 鲁班学院java架构vip课程
1.wps文档地址 https://docs.qq.com/doc/DRVNLUndvTmFSdEhO 2.百度网盘地址 https://pan.baidu.com/s/1uxaTzJZHKrsw_H ...
- 构造器Constructor
构造器Constructor是否可被override构造器Constructor不能被继承,因此不能重写Overriding,但可以被重载Overloading 首先,构造器是不能被继承的,因为每个类 ...
- excel被保护或者锁定时候按住alt和enter可以输入换行
excel被保护或者锁定时候按住alt和enter可以输入换行
- Windows下OpenFOAM开发及使用环境配置指南 (1)【转载】
转载自:http://openfoam.blog.sohu.com/158614863.html *************************************************** ...
- Leetcode题目461:汉明距离(位运算-简单)
题目描述: 两个整数之间的汉明距离指的是这两个数字对应二进制位不同的位置的数目. 给出两个整数 x 和 y,计算它们之间的汉明距离. 注意:0 ≤ x, y < 231. 示例: 输入: x = ...
- 作妖 | "该文件没有与之关联的程序来执行该操作..."的解决方法(删除快捷方式小箭头所致)
文章目录 开始作妖 后悔作妖 终结作妖 开始作妖 这是次很作妖的体验过程.因为重新换了个系统,看着桌面上这些快捷方式都有个讨人嫌的小箭头,就在网上搜了搜解决办法. 比如,将下面的内容复制到记事本中,再 ...