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 ...
随机推荐
- python - Flask 上下文管理 流程
上下文管理: - 请求上下文 (ctx=RequestContext()) : request/session - App上下文 (app_ctx=AppContext()) : a ...
- PowerDesigner创建表 拷贝创建表语句 SQLSERVER创建数据库 使用查询 创建表 并且添加数据
PowerDesigner创建表 : 1.双击打开PowerDesigner 2.双击打开Create model 3左键点击Model types,再点击Physical Data m ...
- Mongo mongoexport/mongoimport介绍
一.Mongoexport导出数据 1,导出json数据 mongoexport -d db -c collection -o save-file.dat 2,导出CSV数据 mongoexport ...
- 二十二. 安装部署Tomcat服务器、使用Tomcat部署虚拟主机、使用Varnish加速Web
web proxy web1 web2 1.安装部署Tomcat服务器 web1 1.1 使用RPM安装JDK环境 ]# yum -y install java-1.8.0-openjdk ]# ...
- python常用函数2
2.reduce()函数 reduce() 函数也是python内置的一个高阶函数.reduce()函数接收的参数和 map()相似,一个函数 f ,一个list,但行为和 map()不同,re ...
- WebSocket浅谈
WebSocket是HTML5开始提供的一种在单个 TCP 连接上进行全双工通讯的协议. 在WebSocket API中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速 ...
- FOI 冬令营 Day6
目录 T1.堆(heap) 传送门 Code T2.密文(secret) 传送门 Code T3.树(tree) 传送门 Code 别问Day5到底去哪里了,咕咕咕 T1.堆(heap) 传送门 Co ...
- LeetCode 第 150 场周赛
一.拼写单词(LeetCode-1160) 1.1 题目描述 1.2 解题思路 由于给定的chars,每个字母只能用一次,所以用大小为26的数组charsArray来表示a-z(例如charsArra ...
- mysql转移Data目录
本来很简单的事,为何这么复杂,转目录后经常不成功.mysql安装时就不能指定数据目录吗?老是默认在C盘 测试环境Windows10, mysql5.7,以下是测试记录: 1. 复制Data到D盘下,如 ...
- Qt之模型/视图(实时更新数据)
上两节简单介绍了Qt中对于模型/视图的编程,大部分助手里说的很清楚了,现在就开始实战部分吧! 在实际应用中,视图展示的数据往往并非一成不变的,那么如何实时更新成了一个很重要的问题!功能:(1)添加委托 ...