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

当对代码进行测试的时候, 我们经常需要用到一些模拟(mock)技术.

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

绿色的是需要被测试的类, 黄色是它的依赖项, 灰色的无关的类

 

在一个项目里, 我们经常需要把某一部分程序独立出来以便我们可以对这部分进行测试. 这就要求我们不要考虑项目其余部分的复杂性, 我们只想关注需要被测试的那部分. 这里就需要用到模拟(Mock)技术.

因为, 请仔细看. 我们想要隔离测试的这部分代码对外部有一个或者多个依赖. 所以编写测试代码的时候, 我们需要提供这些依赖. 而针对隔离测试, 并不应该使用生产时用的依赖项, 所以我们使用模拟版本的依赖项, 这些模拟版依赖项只能用于测试时, 它们会使隔离更加容易.

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

绿色的是需要被测试的类, 黄色Mock的依赖项

 

Mock技术带来的优点

使用Mock技术, 可以有如下的优点:

提高测试运行速度, 例如可以模拟DB, Web Service等比较慢的服务, 以及算法等.

支持并行开发, 例如实际的依赖项还没有完成开发, 或者等待其他团队开发依赖项.

提高测试可靠性, 例如有时这个依赖项的bug太多了, 经常由于依赖项的原因导致测试失败, 那么就应该使用mock版本来验证我们自己写的代码.

减少开发/测试成本, 有时程序可能依赖一些云服务, 这些服务是按调用次数收费的, 那么就可以使用Mock版本来节省这方面的开资, 当然了最后还是需要使用真正的服务测试才行; 有时候组建依赖项太费劲了, 就用mock版本吧, 省时省力.

在有不确定性依赖项的情况下进行测试, 有些依赖项有不确定性, 可能无理由的造成测试失败, 这时候就应该使用mock版本的依赖.

 

单元测试

Mock技术通常在单元测试中使用, 可以使用xUnit来为.NET Core应用做单元测试, 这里有介绍xUnit的文章: https://www.cnblogs.com/cgzl/p/9178672.html#xunit

那么什么是一个单元? 

这个通常是由团队对系统的理解决定, 可以针对一个类, 也可以针对多个类.

单元测试通常具有以下特点:

低级别

高聚焦

执行速度快

容易测试所有执行路径上的代码

 

术语

Test Double (我认为可以翻译为测试替身), 是所有非真实依赖项的总称.

Fake, Fake是那种可以正常工作的实现, 尽管可以正常工作, 但是它们不可以用于生产环境, 例如EFCore里的内存数据库提供商.

Dummy, 有时候, 被测试方法需要一些参数, 但是这些参数实际上并没有用到, 这时就可以创建dummy, 它们的存在只是为了满足调用方法的参数要求.

Stub, (状态测试). 它可以使用很直接的方式模拟依赖项的行为. 例如我们可以使用Stub把相关数据放到内存里查询而不是查询真实的数据库; 如果某个测试类需要依赖项的某个Property的值, 那么stub就设定这个值就行.

Mock, (行为/交互测试). 与Stub不同的是, Mock期待的不是返回值, Mock期待的是动作的执行. 它是依赖项的动态包装, 它可以对哪个方法以什么样的顺序被待测试系统(SUT)调用的这个期待行为进行预编程. 也就是说被测试的系统只有按照特定的顺序调用mock依赖项的特定方法, 那么该系统才算测试通过.

还有其它的一些术语就不介绍了, 主要是这四个.

对于Stub 和 Mock ,可以看下面两张图例:

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

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

 

Moq

官网: https://github.com/moq/moq4

Moq框架可以用来创建dummy, stub 和 mock. 在本文里把这三个东西都叫做mock对象吧.

Moq使用一套API来创建stub和mock对象.

 

准备项目

一个简单的.NET Core控制台项目: https://github.com/solenovex/Moq-Tutorial-Code, 代码是里面的01 before.

该项目非常简单, 是关于球员转会业务, 它目前只有三个类. 

TransferApplication, 球员转会申请类:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zgfzyd.html