NSubstitute入门

最简单的入门方式就是创建一个测试项目,并将 NSubstitute 引用到其中。可以通过 NuGet 或 OpenWrap 来获取 NSubstitute 包。也可以直接下载 NSubstitute 文件,然后将 NSubstitute.dll 引用到项目中。

然后就可以创建一个新的测试 Fixture(可以选择使用你最喜欢的UT测试框架,本文涉及的示例中我们使用MSTest),开始思考从哪里入手。

首先,添加 using NSubstitute; 到当前的C#代码文件中,有了它我们就可以开始创建替身了。

现在,比如我们有一个非常简单的计算器接口:

1     public interface ICalculator
2     {
3       int Add(int a, int b);
4       string Mode { get; set; }
5       event EventHandler PoweringUp;
6     }

我们可以让NSubstitute来创建类型实例的替代实例。可以创建诸如 Stub、Mock、Fake、Spy、Test Double 等,但当我们只是想要一个能有一定程度控制的替代实例时,为什么我们要困扰于此呢?

1     [TestMethod]
2     public void Test_GetStarted_GetSubstitute()
3     {
4       ICalculator calculator = Substitute.For<ICalculator>();
5     }

现在,我们可以告诉被创建的替代实例,当方法被调用时返回一个值:

1     [TestMethod]
2     public void Test_GetStarted_ReturnSpecifiedValue()
3     {
4       ICalculator calculator = Substitute.For<ICalculator>();
5       calculator.Add(1, 2).Returns(3);
6
7       int actual = calculator.Add(1, 2);
8       Assert.AreEqual<int>(3, actual);
9     }

我们可以检查该替代实例是否接收到了一个指定的调用,或者未收到某指定调用:

1     [TestMethod]
2     public void Test_GetStarted_ReceivedSpecificCall()
3     {
4       ICalculator calculator = Substitute.For<ICalculator>();
5       calculator.Add(1, 2);
6
7       calculator.Received().Add(1, 2);
8       calculator.DidNotReceive().Add(5, 7);
9     }

如果 Received() 断言失败,NSubstitute 会尝试给出有可能是什么问题:

1     [TestMethod]
2     [ExpectedException(typeof(ReceivedCallsException))]
3     public void Test_GetStarted_DidNotReceivedSpecificCall()
4     {
5       ICalculator calculator = Substitute.For<ICalculator>();
6       calculator.Add(5, 7);
7
8       calculator.Received().Add(1, 2);
9     }

Expected to receive a call matching:Add(1, 2)
Actually received no matching calls.
Received 1 non-matching call (non-matching arguments indicated with '*' characters):Add(*5*, *7*)

我们也可以对属性使用与方法类似的 Retures() 语法,或者继续使用简单的属性 setter 来设置返回值。

 1     [TestMethod]
 2     public void Test_GetStarted_SetPropertyValue()
 3     {
 4       ICalculator calculator = Substitute.For<ICalculator>();
 5
 6       calculator.Mode.Returns("DEC");
 7       Assert.AreEqual<string>("DEC", calculator.Mode);
 8
 9       calculator.Mode = "HEX";
10       Assert.AreEqual<string>("HEX", calculator.Mode);
11     }

NSubstitute 支持参数匹配功能,可以设置参数规则,并断言判断是否接收到参数匹配的调用。

 1     [TestMethod]
 2     public void Test_GetStarted_MatchArguments()
 3     {
 4       ICalculator calculator = Substitute.For<ICalculator>();
 5
 6       calculator.Add(10, -5);
 7
 8       calculator.Received().Add(10, Arg.Any<int>());
 9       calculator.Received().Add(10, Arg.Is<int>(x => x < 0));
10     }

我们也可以在使用参数匹配功能的同时,传递一个函数给 Returns() ,以此来使替代实例具有更多的功能。

 1     [TestMethod]
 2     public void Test_GetStarted_PassFuncToReturns()
 3     {
 4       ICalculator calculator = Substitute.For<ICalculator>();
 5       calculator
 6          .Add(Arg.Any<int>(), Arg.Any<int>())
 7          .Returns(x => (int)x[0] + (int)x[1]);
 8
 9       int actual = calculator.Add(5, 10);
10
11       Assert.AreEqual<int>(15, actual);
12     }

Returns() 也可通过构造一个返回值序列来指定多个参数。

 1     [TestMethod]
 2     public void Test_GetStarted_MultipleValues()
 3     {
 4       ICalculator calculator = Substitute.For<ICalculator>();
 5       calculator.Mode.Returns("HEX", "DEC", "BIN");
 6
 7       Assert.AreEqual<string>("HEX", calculator.Mode);
 8       Assert.AreEqual<string>("DEC", calculator.Mode);
 9       Assert.AreEqual<string>("BIN", calculator.Mode);
10     }

最后,我们可以在替代实例上引发事件通知:

 1     [TestMethod]
 2     public void Test_GetStarted_RaiseEvents()
 3     {
 4       ICalculator calculator = Substitute.For<ICalculator>();
 5       bool eventWasRaised = false;
 6
 7       calculator.PoweringUp += (sender, args) =>
 8       {
 9         eventWasRaised = true;
10       };
11
12       calculator.PoweringUp += Raise.Event();
13
14       Assert.IsTrue(eventWasRaised);
15     }

基本上这些就是入门 NSubstitute 的全部内容。对于更详细的功能说明,以及一些 NSubstitute 所支持的不太常用的需求,请继续阅读。

NSubstitute 完全手册

  • (一)入门基础
  • (二)创建替代实例
  • (三)设置返回值
  • (四)为特定参数设置返回值
  • (五)为任意参数设置返回值
  • (六)使用函数设置返回值
  • (七)设置多个返回值
  • (八)替换返回值
  • (九)检查接收到的调用
  • (十)清理已收到的调用
  • (十一)参数匹配器
  • (十二)使用回调函数和WhenDo语法
  • (十三)抛出异常
  • (十四)引发事件
  • (十五)自动递归模拟
  • (十六)设置out和ref参数
  • (十七)参数匹配器上的操作
  • (十八)检查调用顺序

NSubstitute完全手册(一)入门基础相关推荐

  1. NSubstitute完全手册(二)创建替代实例

    创建一个替代实例的基本语法: var substitute = Substitute.For<ISomeInterface>(); 这就是通常情况下你创建一个类型的替代实例的方法.一般来说 ...

  2. NSubstitute完全手册(八)替换返回值

    如果需要的话,一个方法或属性的返回值可以被设置多次.只有最后一次设置的值将被返回. 1 public interface ICalculator 2 { 3 int Add(int a, int b) ...

  3. NSubstitute完全手册索引

    NSubstitute 是什么? NSubstitute 是一个 .NET 单元测试模拟类库. 一直以来,开发者对 mocking 类库的语法的简洁性有强烈的需求,NSubstitute 试图满足这一 ...

  4. JSP WEB开发入门基础到高手进阶教程002

    JSP WEB开发入门基础到高手进阶教程 -------开发入门 JSP与微软的Active Server Pages 兼容,但它是使用类似HTML的卷标以及Java程序代码段而不是VBScript. ...

  5. python魔力手册-小白入门宝典:Python快速入门魔力手册 PDF 超清版

    给大家带来的一篇关于Python编程相关的电子书资源,介绍了关于小白入门.python入门.Python手册方面的内容,本书是由魔力手册出版,格式为PDF,资源大小11.8 MB,魔力手册编写,目前豆 ...

  6. phpstudy mysql创建表_MySQL_Mysql入门基础 数据库创建篇,1.创建数据表---基础(高手跳 - phpStudy...

    Mysql入门基础 数据库创建篇 1.创建数据表---基础(高手跳过) 正统方法:create [TEMPORARY] table 表名 [if not exists] (创建的列项定义) [表的选项 ...

  7. linux中vi基础知识,Vim入门基础知识集锦

    想学习Vim,但是Vim官网的手册又太大而全,而网上各方资料要么不全面,要么不够基础.在网上搜集各方资料,按照自己的框架整理一份Vim入门基础教程,分享出来.特点是偏向基础,但对入门者来说足够全面,而 ...

  8. 硬件工程师入门基础知识(一)基础元器件认识(二)

    硬件工程师入门基础知识 (一)基础元器件认识(二) 1.二极管 2.三极管 3.MOS管 4.IGBT 5.晶振 tips:学习资料和数据来自<硬件工程师炼成之路>.百度百科.网上资料. ...

  9. linux小白入门基础命令(一)

    从今天开始汇总一些linux的常用命令,不会太全,这个博客(一)只介绍帮助命令.目录命令和文件操作命令,这个入门基础命令适合linux的初学者,也方便山东科技大学的linux操作系统.docker等涉 ...

最新文章

  1. 敏捷开发日常跟进系列之二:燃尽图(中)
  2. SpiderMonkey-让你的C++程序支持JavaScript脚本
  3. 接口请求时params与data的区别
  4. 疫情启示录:控疫复工背后的数据中心价值,市场这样说
  5. spark的数三角形算法_数据算法 Hadoop Spark大数据处理技巧 PDF 下载
  6. Spring @PostConstruce 和 @PreDestroy 实例化\销毁 bean 时
  7. python ls_linux 常用shell命令 ls
  8. 对比Vector、ArrayList、LinkedList有何区别(转)
  9. jdbc 通过反射和元数据编写通用的查询对象方法
  10. JS编程:查找数组元素位置
  11. Centos 8 安装向日葵(sunloginclient-10.0.0-1)
  12. 计算机基础和办公软件应用第23集,计算机基础及Office办公软件应用(Windows7+0ffice 2010版)...
  13. 新巴巴运动网项目需求书_巴巴姆少儿英语项目介绍(613岁)
  14. 内容市场的2017年:五件大事,每件事都惊心动魄
  15. 系统性谈谈软件可靠性——第2讲:软件可靠性度量及分配
  16. 区块链 数据交易专利
  17. 公众号网课搜题系统-掘光者题库
  18. stimulsoft oracle,报表仪表设计器Stimulsoft的处理数据功能
  19. 查询病案首页最后保存时间
  20. Java实现 word.excel等文档在线预览

热门文章

  1. Python模块: 命令行解析optionparser
  2. Hadoop官方文档翻译——MapReduce Tutorial
  3. swift:Optional Type 、Swift和Objective-C混编的讲解
  4. Ubuntu下MySQL忘记root密码重置
  5. Json 时间 转换为 Javascript 时间 Date Jquery 调用WCF
  6. ACM PKU 2299 Ultra-QuickSort
  7. List和DataTable的Limit
  8. String到底是值类型还是引用类型(C#)
  9. C#中Invoke 和 BeginInvoke的涵义和区别
  10. python pack属性_python tkinter基本属性详解