在做测试的时候,通常会临时替身来协助我们完成测试。
因为不能被测试(SUT))在测试环境下依赖的组件正常使用。如外部系统。
当在一个不能使用真实依赖组件(depended-on component(DOC))的地方写test时,我们可以使用Test Double [1]。
测试双
测试双重起来,有以下几种:
Martin Fowler在Mocks Aren't Stubs [2]中翻译解释:
Martin Fowler的解释还不是太明白,我又收集了更明白一点的解释[3]:
• Dummy - 只是为了满足 API 的虚假值
示例:如果您正在测试一个类的方法,该方法在构造函数中需要许多强制参数,而这对您的测试没有影响,那么您可以创建虚拟对象来创建类的新实例。
• Fake - 创建一个类的测试实现,该类可能依赖于某些外部基础设施。(最好的做法是您的单元测试实际上并不与外部基础设施交互。)
示例:创建用于访问数据库的假实现,将其替换为内存中的集合。
• Stub - 覆盖方法以返回硬编码值,也称为基于状态的
示例:您的测试类依赖于一个方法 calculate() 需要 5 分钟才能完成。您可以用返回硬编码值的存根替换它的实际实现,而不是等待 5 分钟;只花费一小部分时间。
• Mock - 与 Stub 非常相似,但基于交互而不是基于状态。这意味着您不期望 Mock 返回一些值,而是假设进行方法调用的特定顺序。
示例:您正在测试一个用户注册类。调用 save 后,它应该调用 send ConfirmationEmail。
上面的已经很明白了,简单概括一下:
Dummy:主要是使用填充参数,以构造需要测试的对象
Fake:简单的模拟实现,如道,但只是空实现
Stub:相对来说点硬件编码返回值,那么很相似
模拟:相对状态验证更多是行为验证
读到这里每周一次大明白的方式,还有点模糊,要理解和理解了更清晰的区别,需要先了解生命周期
1、生命周期
测试都是由追踪追踪的阶段:
初始化(SetUp)、执行测试(Exercise)、验证结果(Verify)和受伤(Teardown)
2、验证方式
在验证阶段,通常有状态验证方式:验证与行为验证
状态验证:
//肯定会使用的assertassert Equals(expected,actual);
行为验证:
//Mockito中的verifyverify (mock, times(3)).do();
徐昊老师的描述:
万恶淫为首,论无处心,论心世上少人;过程不有趣,只看结果。结果验证
百为孝为先,论心无善,论贫家无孝子;看重过程,不看重结果。
所以我们鉴定淫棍总比鉴定孝子准确
测试策略是要保证的有效性,同时降低测试成本。
假的、存根的、模仿的,越来越低,同时也可靠低。
spy 与 mock 在使用时可能会区分出它们之间的区别,与 stub 的区别,定义看的。
徐昊老师引入过程的视角来进一步:
各个进程之间的存根就是假的,进程之间的存根就是假的。
结合以上的解释很明显,当使用数据库时,伪造一个内存数据库。
以过程划分:
进程间替身:dummy fakespy
进程内替身:stub mockspy
以验证方式划分:
严格来说,我们状态验证使用假存根,行为验证使用模拟。
dummy 和 spy 没有验证,dummy 是不能检验,spy 是测试检验。
spy可以按状态(比如比)也可以按行为(比如)验证。
spy 已经在行为验证和状态验证的边上。spy 是记录调用,对调用加上验证就是模拟
如果用记录来回复就是录播测试,比如你在两个系统间做了spy,把请求和结果播放出来,这样就相当于用spy的数据做的tub了。
请求把结果和目标结果做对比,实际拿spy数据做mock
spy本身只是取而不是一种数据内部数据验证技术,而是正常身份。
间谍是愚蠢的嘲笑
总结
中测试 Double 中的,Test Double 的形式有 dummy fake stub spy mock,以流程维度与验证方式维度能够更好地测试测试策略是要保证的同时,降低测试成本。地区分他们。
参考
[1]
Test Double: http: //xunitpatterns.com/Test%20Double.html
[2]
Mocks Aren't Stubs: https
[3]
: //martinfowler.com/articles/mocksArentStubs.html收集了更清楚一点的解释: https://code-examples .net/en/q/34c8d7