首先介绍各种各样的Test Double(测试替身)
当谈到mock,spy,stub等名词时,小伙伴们想必都是一脸懵逼。今天趁着学到了TDD,我们就来聊一聊各种Test Double(一开始接触这个词我真以为是双倍测试的意思(lll¬ω¬))
人们常说的Test Double共五种,他们分别是:
-
Dummy
- Dummy从未被使用过,仅用来填写参数列表。
-
Fake
- Fake 可以是某个 Data Access Object 或者 Repository 的基于内存的实现;该实现并不会真的去进行数据库操作,而是使用简单的 HashMap 来存放数据。
- 能够迅速地实现系统原型,并且基于内存存储来运行整个系统,推迟有关数据库设计所用到的一些决定。
- 例如:利用 Fake 来保证在测试环境下支付永远返回成功结果。
-
Stub
- Stub 代指那些包含了预定义好的数据并且在测试时返回给调用者的对象。
- Stub 常被用于我们不希望返回真实数据或者造成其他副作用的场景。
- 例如:当某个对象需要从数据库抓取数据时,我们并不需要真实地与数据库进行交互或者像 Fake 那样从内存中抓取数据,而是直接返回预定义好的数据。
-
Spy
- 是Stub,且还会根据调用方法记录一些信息。
- 例如:记录已发送了多少封邮件。
-
Mock
- Mock代指那些仅记录它们的调用信息的对象,可以用verify(mockInstanceName)验证行为(方法)是否发生
- 当我们并不希望真的调用生产环境下的代码或者在测试中难于验证真实代码执行效果的时候,我们会用 Mock 来替代那些真实的对象。
- 例如:对邮件发送服务的测试,我们并不希望每次进行测试的时候都发送一封邮件,毕竟我们很难去验证邮件是否真的被发出了或者被接收了。我们更多地关注于邮件服务是否按照我们的预期在合适的业务流中被调用
And 我的一些个人理解
看了网上的各种文章,感觉讲的都晕乎乎的,突然灵光一闪,自己想了一个例子,希望能够帮助各位小伙伴理解。(如有错误欢迎指正)
首先建立一个上下文: 我们工厂需要做一截管道,功能是当监测到沙水通过时,自动打开滤网,把沙水过滤成清水。(基于此上下文)
-
把它放到整个或部分管道系统中去,放水(或者其他各种液体),测试它能不能正常运行(集成测试);
-
通过各种其他做好的模具,即“测试替身”(或测试管道用的机器,喷清水机,喷沙水机,识别水质机这种)组装起来测试其功能(单元测试);
-
入口接上喷清水,沙水机(Fake),看看能不能输出清水;
-
出口模拟出液体(Stub),看看水能不能进去(有点儿牵强了;
-
当沙水过管道时,管道内的滤网扣会打开,此时过滤网会掉出来。我给它进了沙水,想观察滤网扣打开了吗(Mock),此时不需要管有没有滤网,只是想观察滤网扣的行为;
-
为了想知道这个滤网一小时内能不能连续打开十次,我在外面加了个计数器,监测它一段时间内打开的次数(Spy);
-
每截生产出来的管道都要贴个标才能用,(虽然不贴也能用,但是就是有这么个硬性规定,所以我们给它先整了个无关紧要的标贴上去了(Dummy)