文档章节

单元测试(四)-隔离框架NSubstitute

zhixin9001
 zhixin9001
发布于 2017/05/27 22:05
字数 700
阅读 54
收藏 0

之前学习了单元测试的基础知识,以及桩对象和模拟对象的不同作用。但在实际应用中,往往不会直接手写桩对象或者模拟对象,而是使用隔离框架动态的创建这些对象,这可以让测试变得更简便、快捷,还可以更好地应对复杂的测试。这里学习的便是隔离框架的一种——Nsubstitute。

 

一 开始使用NSubstitute

在前面有一个测试场景为:使用LogAnalyzer.Analyze方法分析文件,如果文件名过短,就记录日志,为了测试LogAnalyzer类与ILogger实现之间的交互,需要手写一个实现了ILogger接口的模拟对象,并针对这个模拟对象进行断言。那么现在使用NSubstitute来进行这一过程,测试代码只有下面几行就可以做到了。

 

logger就是使用NSubstitute创建的模拟对象。Substitute静态类动态负责创建伪对象,For 方法是产生伪对象的基本方法。最后一句中的logger.Receive方法在接口中并不存在,而是被NSubstitute扩充的,用于验证方法是否被调用。logger.Received().LogError("Filename too short:a.txt")整体的意思便是:测试logger对象是否Receive对LogError方法的调用请求,而且传递的参数为"Filename too short:a.txt"。这是对模拟对象的测试方法。

 

 

 

二 设置伪对象的返回值

还可以设置方法在一定条件下的返回值

a) 全匹配

 

rule.IsValidLogFileName("a.txt").Returns(true),指定了当方法IsValidLogFileName()被调用且参数为"a.txt"时返回结果为true

 

b) 类型匹配

 

rule.IsValidLogFileName(Arg.Any<string>()).Returns(true),指定了当方法IsValidLogFileName()被调用且参数为string类型时返回结果为true,这样匹配的范围会更广,这种指定方法也最常用。类型匹配主要使用Arg来指定

 

c) 返回异常

 

还可以指定方法在一定的条件下返回何种异常,比如这儿的代码中指定的条件为IsValidLogFileName()被调用且参数为string类型时,返回Exception("fake exception")。这儿的写法与前面的有点区别,用到了lambda表达式

 

 

 

 

三 使用隔离框架的注意事项

a) 隔离框架的写法会使代码可读性降低

b) 明确要验证的对象,不要验证错误的事情,也不要过度验证

c) 尽量少用模拟对象,一个测试中最多出现一个模拟对象,但模拟对象存在时,要针对模拟对象进行断言

d) 不要使用桩对象来验证交互,这是模拟对象做的事情

 

参考资料:

The Art of Unit Testing with examples in C#, 2nd Edition by Roy Osherove

 

© 著作权归作者所有

zhixin9001
粉丝 6
博文 103
码字总数 87823
作品 0
西安
私信 提问
c++ 单元测试框架 gmock 深度剖析

c++ 单元测试框架 gmock 深度剖析 随着微服务和CI的流行,在目前的软件工程领域中单元测试可以说是必不可少的一个环节,在TDD中,单元测试更是被提高到了一个新的高度。但是很多公司由于很多...

SolidMango
2018/08/19
0
0
使用模拟测试框架的 5 个理由

背景 研究人员和专家已经声明了敏捷和单元测试的主流.如果你所使用的正好在主流框架中那是个好消息。但是如果你的公司被夹在漩涡中间怎么办?现在你正在试图让你的公司加快速度并且对你的代码...

oschina
2013/07/24
2.5K
10
Android单元测试只看这一篇就够了

本文由 玉刚说写作平台 提供写作赞助,版权归 微信公众号所有 原作者:Jdqm 版权声明:未经 许可,不得以任何形式转载 单元测试是应用程序测试策略中的基本测试,通过对代码进行单元测试,可...

Jdqm
2018/07/25
0
0
如何高效进行白盒单测

之前为写了写单元测试的基础原理和简单的环境调试,这次就简述一下在进行单元测试是需要注意的东西和基础框架。 首先,要做好单测,首先要捋清楚开发的代码结构,为成功搭建单测环境奠定基础...

fiawfo
2016/11/23
60
0
仓储(Repository)和工作单元模式(UnitOfWork)

仓储和工作单元模式 仓储模式 为什么要用仓储模式 通常不建议在业务逻辑层直接访问数据库。因为这样可能会导致如下结果: 重复的代码 编程错误的可能性更高 业务数据的弱类型 更难集中处理数...

JoeSnail
2018/01/18
0
0

没有更多内容

加载失败,请刷新页面

加载更多

好文:华杉:我等用功,不求日增,但求日减。减一分人欲,则增一分天理,这是何等简易!何等洒脱!

#写在前面1.怎么理解“减一分人欲,则增一分天理,这是何等简易!”?1)华杉提倡 “一劳永逸” 排除浪费,少干活,多赚钱,一战而定,降低作业成本。2)华杉提倡学海无涯,回头是岸...

阿锋zxf
27分钟前
3
0
vue 的bus总线

bus声明 global.bus = new Vue() 事件发送 controlTabbar () {global.bus.$emit('pickUp', 'ddd')}, 事件接收 global.bus.$on('pickUp', (res) => {this.isFocus = true})......

Js_Mei
32分钟前
2
0
大型系统演进之路-负载均衡演进

Nginx做负载均衡 通过Nginx的反向代理将请求分发到tomcat中,如果tomcat支持100并发,Nginx支持50000并发,理论上nginx把请求发送到500个tomcat就可以了。 LVS或F5做多个Nginx负载均衡 Tomc...

春哥大魔王的博客
37分钟前
4
0
Sqlite时间段查询中遇到的问题

问题: 我要查询DateTime时间其中的一段符合时间要求的数据,比如我要查询‘2019-06-06 16:50:00’至‘2019-06-06 16:59:00’这一段的数据 开始用这段代码 strSql= ("select * from Coll...

rainbowcode
41分钟前
2
0
大数据(hadoop-数据入库系统Sqoop原理架构)

Sqoop是什么 Sqoop:SQL-to-Hadoop 连接传统关系型数据库和Hadoop的桥梁 把关系型数据库的数据导入到 Hadoop 系统 ( 如 HDFS、HBase 和 Hive) 中; 把数据从 Hadoop 系统里抽取并导出到关系型...

这很耳东先生
55分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部