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

单元测试(四)-隔离框架NSubstitute的更多相关文章

  1. [Test] 单元测试艺术(2) 打破依赖,使用模拟对象,桩对象,隔离框架

    在上节中,完成了第一个单元测试,研究了各种特性,在本节,将介绍一些更实际的例子.SUT依赖于一个不可操控的对象,最常见的例子是文件系统,线程,内存和时间等. 本系列将分成3节: 单元测试基础知识 打破 ...

  2. 使用四种框架分别实现百万websocket常连接的服务器

    著名的 C10K 问题提出的时候, 正是 2001 年.这篇文章可以说是高性能服务器开发的一个标志性文档,它讨论的就是单机为1万个连接提供服务这个问题,当时因为硬件和软件的**,单机1万还是一个非常值 ...

  3. 使用四种框架分别实现百万websocket常连接的服务器--转

    原文地址:http://colobu.com/2015/05/22/implement-C1000K-servers-by-spray-netty-undertow-and-node-js/#Nett ...

  4. python学习笔记(十五)-unittest单元测试的一个框架

    unittest 单元测试的一个框架什么框架 一堆工具的集合. TestCase TestSuite 测试套件,多个用例在一起 TestLoader是用来加载TestCase到TestSuite中的 ...

  5. 如何在单元测试时隔离ORM

    在项目中需要对DAL层进行单元测试,如果直接操作数据库,首先测试速度会大大下降,而且让单元测试直接使用外部依赖,很可能带来后续维护的不便,所以有必要对数据库隔离,然后单独测试DAL层.由于使用了ORM ...

  6. python之单元测试及unittest框架的使用

    例题取用登录模块:代码如下 def login_check(username,password): ''' 登录校验的函数 :param username:账号 :param password: 密码 ...

  7. 【Html 学习笔记】第四节——框架

    我们经常使用的网页可能不是一个单独的网页,而是多个嵌套的,那么就需要用到下面的技术. 垂直框架:<frameset cols=""> 这里需要注意的是:四个网页需要同时 ...

  8. Python单元测试unittest测试框架

    本文的主题是自动化测试框架的实现,在实现之前,先了解一下关于unittest模块的相关知识: Python中有一个自带的单元测试框架是unittest模块,用它来做单元测试,它里面封装好了一些校验返回 ...

  9. 单元测试利器Mockito框架

    什么是Mock Mock 的中文译为仿制的,模拟的,虚假的.对于测试框架来说,即构造出一个模拟/虚假的对象,使我们的测试能顺利进行下去. Mock 测试就是在测试过程中,对于某些 不容易构造(如 Ht ...

随机推荐

  1. macbook 安装oracle RAC

    http://blog.itpub.net/29047826/viewspace-1268923/ http://blog.itpub.net/24930246/viewspace-1426856/

  2. python 生成器 迭代器

    阅读目录 一 递归和迭代 二 什么是迭代器协议 三 python中强大的for循环机制 四 为何要有for循环 五 生成器初探 六 生成器函数 七 生成器表达式和列表解析 八 生成器总结 一 递归和迭 ...

  3. Mysql的优化一则

    目的在于这么一个sql语句: SELECT w.* FROM wallpaper w inner join wallpaper_category_relation r ON w.wallpaper_i ...

  4. .net core2 mvc项目中,加入RazorPages页面

    2017.08.22 试验结果: 1.手工添加/Pages文件夹 2.复制/Views/_ViewImports.cshtml到/Pages/_ViewImports.cshtml  2.1 修改@u ...

  5. 【JAVA】类加载器

    在Java中主要有一下三种类加载器; Booststrap ClassLoader:此加载器采用C++编写,一般开发中是看不到的: Extendsion ClassLoader:用来进行扩展类的加载, ...

  6. 接口测试学习笔记(Jmeter)

    常见接口协议: 1.http 超文本传输协议 2.https 安全超文本传输协议 3.ftp 文件传输协议 4.tcp 网络控制协议 5.IP 互联网协议 6.udp 用户数据协议 -- HTTP协议 ...

  7. postgresql主从配置

    master:10.0.1.114 slaver:10.0.1.116 一.yum安装https://blog.csdn.net/weixin_41048363/article/details/803 ...

  8. centos7 安装配置zookeeper

    https://blog.csdn.net/AaronLin6/article/details/78438877 https://www.cnblogs.com/sxdcgaq8080/p/74924 ...

  9. Nginx缓存配置

    访问我的博客 前言 本文介绍利用 nginx 的 nginx_ngx_cache_purge 模块来实现缓存功能,前几篇文章介绍了 Nginx 的动静分离以及 CDN 技术,在其基础上,再对整个页面进 ...

  10. CentOS 7通过RVM来安装指定版本的Ruby

    RVM也就是Ruby Version Manager,Ruby版本管理器 1.安装依赖库: yum install gcc-c++ patch readline readline-devel zlib ...