第一篇文章, 关于Mock的概念介绍: https://www.cnblogs.com/cgzl/p/9294431.html

本文介绍使用Moq来Mock方法.

使用的代码: https://github.com/solenovex/Moq4-Tutorial-Code 里面的 02 Before 部分.

Mock 对象

紧接着上文中的例子. 上一篇文章, 我在单元测试的时候, 把依赖项设为null:

然后便出现了NullReferenceException, 导致测试无法正常运行.

首先应该做的是在TransferApproval的构造函数里判断参数是否为null, 如果为null的话应该抛出ArgumentNullException:

这是更恰当的异常.

这样的话, 在测试的时候, 抛出的就是ArgumentNullException了, 它可以更恰当的表达程序出现的问题:

现在我们可以使用mock版本的依赖项来代替null了:

上面的代码首先使用Moq创建了一个mock版本的IPhysicalExamination的实例.

而由于Moq对依赖项进行了包装, 所以要获得实际的mock依赖项, 我们需要使用mockExamination.Object属性. 而这个属性的类型就是IPhysicalExamination.

另外一个测试方法我也这么改一下, 然乎重新Build. Run All Tests:

还是红色的, 但现在是测试没通过, 并不是抛出异常.

测试没通过的意思就是期待值和实际返回值不符.

让我们来调试一下这个测试, 我在TransferApproval类里面设置一个端点, 查看一下这个mock依赖项的方法返回值:

然后调试测试:

跑到断点

可以看到这个Mock版本依赖项的IsHealthy()方法的返回值是false.

我并没有对这个Mock版本的IPhysicalExamination的IsHealthy()方法设定返回值, 正因为如此, 它才会返回它方法返回类型的默认值, 它的返回类型是bool, 而bool的默认值是false, 所以现在IsHealthy()方法在没有设定的情况下的返回值就是false.

It类

而PhysicalExamination这个具体的实现类由于各种原因导致还没有实现, 为了让它不妨碍我们的单元测试, 我先设定让它在无论传进什么参数的情况下都会返回true.

从业务上来讲就是假设所有转会球员都可以通过体检:

那么现在所有的测试都应该可以通过了:

这里用到了It这个类, 在Moq里, It这个类是用来做参数匹配的, it 就是"它"的意思, 它就代表需要被匹配的参数.

It.IsAny<T>(), 它表示传递给方法的参数的类型只要是T就可以, 值是任意的. 只要满足了这个条件, 那么方法的返回值就是后边Returns()方法里设定的值.

Moq 关于It类的文档: http://www.nudoq.org/#!/Packages/Moq/Moq/It

它有下面几种用法:

  • Is<TValue>(Expression<Func<TValue, Boolean>>)
  • IsAny<TValue>()
  • IsIn<TValue>(IEnumerable<TValue>)
  • IsInRange<TValue>(TValue, TValue, Range)
  • IsNotIn<TValue>(IEnumerable<TValue>)
  • IsNotNull<TValue>()
  • IsRegex(string)

我认为通过方法名就可以知道这些方法的用途.

下面我修改一下该测试方法, 使用It其它几个方法:

其测试结果仍然是通过的.

严谨(Strict) vs 宽松(Loose) Mock

Moq里面有Strict(严谨)和Loose(宽松) mock对象的概念, 当然也有很多人不喜欢这个概念.

在当前的测试方法里, TransferApproval依赖于Mock<IPhysicalExamination>, 并调用其IsHealthy()方法.

如果不对IsHealthy()方法进行任何设定的情况下, 方法会返回bool的默认值false, 这种就是loose(宽松) Mock.

在创建Mock对象的时候, 还可选传递一个MockBehavior这个参数.

MockBehavior是一个枚举, 它有三个值:

  • MockBehavior.Strict, 如果mock对象上的方法没有被预先设置好, 那么测试中调用该方法的时候就会抛出异常.
  • MockBehavior.Loose, 即使方法没有被预先设置, 调用它的时候也不会抛出异常. 它会返回该方法返回类型的默认值.
  • MockBehavior.Default, 它代表MockBehavior.Loose.

如果上例使用Strict Mock, 那么将会抛出Exception:

下面我把一个测试改为Strict Mock, 并取消了对IsHealthy()方法的设置:

而测试时会抛出MockException:

在对方法进行设置后, 测试就会通过:

可以感觉到:

Loose Mock, 可以少写一些设定代码, 可以返回默认值, 不易让测试中断

Strict Mock, 需要写跟多的设定代码, 每个被调用的方法都需要进行设定, 所以也更容易让测试中断.

Moq的建议是: 大多数情况下应该使用Loose Mock, 只有特殊需要的时候才去使用Strict Mock.

out参数

修改一下TransferApproval类的转会审批方法:

这次使用的是带有out参数的IsHealthy()方法.

建立一个测试方法, 并设定这个带有out参数的方法:

很简单, 测试会通过:

完成的代码在: https://github.com/solenovex/Moq4-Tutorial-Code 02 After

未完待续....

使用 Moq 测试.NET Core 应用 -- Mock 方法的更多相关文章

  1. 使用 Moq 测试.NET Core 应用 -- Mock 属性

    第一篇文章, 关于Mock的概念介绍: https://www.cnblogs.com/cgzl/p/9294431.html 第二篇文章, 关于方法Mock的介绍: https://www.cnbl ...

  2. 使用 Moq 测试.NET Core 应用 -- Mock 行为

    第一篇文章, 关于Mock的概念介绍: https://www.cnblogs.com/cgzl/p/9294431.html 第二篇文章, 关于方法Mock的介绍: https://www.cnbl ...

  3. 使用 Moq 测试.NET Core 应用

    第一篇文章, 关于Mock的概念介绍: https://www.cnblogs.com/cgzl/p/9294431.html 第二篇文章, 关于方法Mock的介绍: https://www.cnbl ...

  4. 使用 Moq 测试.NET Core 应用 - Why Moq?

    什么是Mock 当对代码进行测试的时候, 我们经常需要用到一些模拟(mock)技术. 绿色的是需要被测试的类, 黄色是它的依赖项, 灰色的无关的类 在一个项目里, 我们经常需要把某一部分程序独立出来以 ...

  5. 使用 Moq 测试.NET Core 应用 -- 其它

    第一篇文章, 关于Mock的概念介绍: https://www.cnblogs.com/cgzl/p/9294431.html 第二篇文章, 关于方法Mock的介绍: https://www.cnbl ...

  6. Moq 测试 属性,常用方法

    RhinoMock入门(7)——Do,With和Record-playback 摘要: (一)Do(delegate)有时候在测试过程中只返回一个静态的值是不够的,在这种情况下,Do()方法可以用来在 ...

  7. Moq 在.net Core 单元测试中的使用

    Moq,主要用来伪造接口的实现类,实现方法,属性 moq The most popular and friendly mocking framework for .NET What? Moq (pro ...

  8. Mock方法介绍

    1 现有的单元测试框架单元测试是保证程序正确性的一种有效的测试手段,对于不同的开发语言,通常都能找到相应的单元框架. 借助于这些单测框架的帮助,能够使得我们编写单元测试用例的过程变得便捷而优雅.框架帮 ...

  9. linux下生成core dump文件方法及设置【转】

    转自:http://blog.csdn.net/mrjy1475726263/article/details/44116289 源自:http://andyniu.iteye.com/blog/196 ...

随机推荐

  1. javascript 面向对象程序设计--深刻理解对象

    javascript中,每个对象都是基于一个引用类型创建的,我们可以把ECMAScript 的对象想象成散列表:无非就是一组名值对,其中值可以是数据或函数. 深刻理解对象 创建自定义对象的最简单方式就 ...

  2. 使用STM32Cube在STM32F7开发板上实现SD+Freertos+Fatfs

    简介 最近项目中可能需要使用到SD卡,所以需要对SD卡的配置和使用调研,在配置过程中遇到了一些问题,在此记录一下. STM32Cube配置 Pinout 只需要注意绿色部分的设定 Clock配置 这里 ...

  3. Python Assert 为何不尽如人意

    Python中的断言用起来非常简单,你可以在assert后面跟上任意判断条件,如果断言失败则会抛出异常. >>> assert 1 + 1 == 2 >>> ass ...

  4. python里如何保存float类型的小数的位数

    python保留两位小数: In [1]: a = 5.026 In [2]: b = 5.000 In [3]: round(a,2) Out[3]: 5.03 In [4]: round(b,2) ...

  5. 在centos上面安装phantomjs

    在opt目录下创建phantomjs文件夹 mkdir -p /opt/phantomjs 把phantomjs解压出来的的文件放到/opt/phantomjs下面 建立软链接 ln -s /opt/ ...

  6. LinkedBlockingQueue简介

    LinkedBlockingQueue是一个单向链表实现的阻塞队列,先进先出的顺序.支持多线程并发操作. 相比于数组实现的ArrayBlockingQueue的有界,LinkedBlockingQue ...

  7. BZOJ_2661_[BeiJing wc2012]连连看_费用流

    BZOJ_2661_[BeiJing wc2012]连连看_费用流 Description 凡是考智商的题里面总会有这么一种消除游戏.不过现在面对的这关连连看可不是QQ游戏里那种考眼力的游戏.我们的规 ...

  8. POJ_3342_Party at Hali-Bula_树形DP

    POJ_3342_Party at Hali-Bula_树形DP 题意:直接上司和本人不能同时参加,求最多参加人数,并回答是否唯一解. 分析:常规树形DP,需要再维护一下选/不选当前点取得最大值时是否 ...

  9. Docker系列之swarm集群搭建

    学习Docker很久了,今天分享一下Docker的swarm集群的搭建过程很简单 首先第一步是 每台机器上面都要安装docker 本人使用的是centos7操作系统,使用3太虚拟机,3太虚拟机必须网络 ...

  10. MIP 技术进展月报:储存功能全新上线,MIP-Cache域名升级,校验更严谨

    集 ** 瞬时触达用户.高转化率.炫酷闪电标.优质展现形式 ** 等诸多特性为一体的 MIP 页面吸引了众多站点进行改造.为了更好地服务于广大站长,更快地倾听站长们的声音,MIP 技术团队特推出< ...