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 ...
随机推荐
- Soda Theme sublime 自定义编辑器主题
1.Soda ThemeSublime Text 3中较为常用的一款自定义编辑器主题,用过的人都说好.Soda Theme包含代码着色.标签.图标,拥有light和dark两种颜色主题便于用户在不同时 ...
- javascript权威指南第16章 HTML5脚本编程
<!DOCTYPE html> <html> <head> <script type="text/javascript" src=&quo ...
- React应用数据传递的方式
1. props属性 典型的React应用,数据通过props按照自上而下(父->子)的顺序传递数据. 2. Context传值 1. 应用场景 对于一些应用中全局性的属性(如UI主题.语言.登 ...
- 010_Python3 字典
字典是另一种可变容器模型,且可存储任意类型对象. 字典的每个键值(key=>value)对用冒号(:)分割,每个对之间用逗号(,)分割,整个字典包括在花括号({})中 ,格式如下所示: d ...
- AGC037C Numbers on a Circle【构造】
从后往前做,每次将\(B_i\)减去相邻两个数,注意如果最大的数没有变成初始状态,那么肯定要减,否则相邻两边的就减不了,所以用堆维护.根据辗转相除的复杂度,\(O(n\log^2 n)\). #inc ...
- geometry_msgs/PoseStamped 类型的变量的构造
#navpoint.msg geometry_msgs/PoseStamped target_pose uint8 floor uint8 type target_pose 的类型为geometry_ ...
- jmeter接口上传图片功能
图片上传需要选择Files Upload 输入下列参数: File Path:方法一,把图片放在bin目录下,直接输入图片名称:方法二,点击下图“Browse”按钮,选择一张需要上传的图片,地址将会自 ...
- [TJOI2019]甲苯先生和大中锋的字符串——后缀自动机+差分
题目链接: [TJOI2019]甲苯先生和大中锋的字符串 对原串建后缀自动机并维护$parent$树上每个点的子树大小,显然子树大小为$k$的节点所代表的子串出现过$k$次,那么我们需要将$[len[ ...
- vue要注意的小知识
心灵的鸡汤 https://www.zhangxinxu.com/wordpress/2017/06/ten-question-about-frontend-zhihu/ 1.第三方的js文件只能放在 ...
- Radix Heap ---Dijkstra算法的优化 BY Gremount
Radix Heap 算法是在Dijkstra的Dial实现的基础上,通过减少对桶的使用,来优化算法的时间复杂度: Dial 时间复杂度是O(m+nC) -------C是最长的链路 Radi ...