前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Moq基础(六)

Moq基础(六)

作者头像
黄腾霄
发布2020-06-10 10:58:46
8630
发布2020-06-10 10:58:46
举报
文章被收录于专栏:黄腾霄的博客

这一章是最后一讲,我们讲一下Moq中值得注意的小技巧,以及对Moq使用的评价


MockBehavior:伪对象行为

在使用Moq创建伪对象时,可以在构造函数里传入MockBehavior

MockBehavior有了两种:

  • Loose:默认行为,任何未显示伪造的方法和属性都会返回默认值,且不会抛出异常。
  • Strict: 任何调用都需要显式Setup,并使用VerifyAll验证。

什么意思呢?如下图所示,你要验证公共方法A,A中做了T.B()T.C()两件事。

代码语言:javascript
复制
public void A()
{
   Name = T.B();
   Age = T.C();
}

Loose允许你测试A时只伪造方法B,并验证Name状态,

Strict要求必须同时伪造方法BC,否则会抛出异常。

同样,另一方面,如果后期方法A又调用了一个T.D(),那么前者的测试会过,后者会失败,提醒用户修改测试。

至于选择,我个人是没有什么偏好,大家自己喜欢就好。


CallBase :调用基类方法

如果你期望某些方法调用原类型虚方法的默认实现,可以使用

代码语言:javascript
复制
var mock = new Mock<Foo> { CallBase = true };

这个在测试有一大堆虚方法的基类时十分有效,不用为了测一个方法,伪造过多其他方法。


SetupSequence :伪造序列

如果你期望,一个方法每次调用返回值都不同,那么可以试试下面的写法。

代码语言:javascript
复制
var mock = new Mock<IFoo>();
mock.SetupSequence(f => f.GetCount())
    .Returns(3)  // will be returned on 1st invocation
    .Returns(2)  // will be returned on 2nd invocation
    .Returns(1)  // will be returned on 3rd invocation
    .Returns(0)  // will be returned on 4th invocation
    .Throws(new InvalidOperationException());  // will be thrown on 5th invocation

值得注意的是如果你期望,该方法被调用4次,那么一定要在第5次(最后一句)

Throws(new InvalidOperationException()) 中断测试,否则会返回Null


Protected():伪造Protected成员

如果需要测试Protected成员的行为,你可以使用下面的方式(不过到了这一步,可能已经意味着你的代码需要再审查一遍结构是否合理了)

代码语言:javascript
复制
//无参数
mock.Protected()
     .Setup<int>("Execute")
     .Returns();
//带参数
mock.Protected()
    .Setup<string>("Execute",
        ItExpr.IsAny<string>())
    .Returns(true);

值得注意的是,因为Protected成员“不可见”,因此只能使用字符串进行处理


Internal程序集可见

有时候我们会需要测试一些Internal的类和方法,此时我们不仅需要对测试项目可见,还要对测试框架的生成器可见。

因此需要在AssemblyInfo.cs添加

代码语言:javascript
复制
[assembly:InternalsVisibleTo("DynamicProxyGenAssembly2")]
[assembly:InternalsVisibleTo("YourTestProject")]

ok,以上是Moq基础的全部知识性内容。

下面说说对Moq的看法。

Moq作为一个受限的单元测试框架,做到了免费,简单,易用。

应该说能够满足大部分的应用需求。

对于一个项目来说,如果Moq能够满足使用需求,那这个项目一定是SOLID

当然,对于一些遗留代码来说,通常需要非受限框架对他进行支持(例如typemock isolator,MS Fakes)

不足之处是,Moq的概念存在一些混淆,往往容易将初学者带偏,一些API设计也有待商榷。

但是,Moq只是我们书写单元测试的工具,他真正的威力在于使用者。

兵无常势,水无常形。框架总会更新,创建测试的能力才是需要保留的。


本文会经常更新,请阅读原文: https://xinyuehtx.github.io/post/Moq%E5%9F%BA%E7%A1%80-%E5%85%AD.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名黄腾霄(包含链接: https://xinyuehtx.github.io ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-04-19 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • MockBehavior:伪对象行为
  • CallBase :调用基类方法
  • SetupSequence :伪造序列
  • Protected():伪造Protected成员
  • Internal程序集可见
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档