You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Test lifecycle with stubs:
Setup - Prepare object that is being tested and its stubs collaborators.
Exercise - Test the functionality.
Verify state - Use asserts to check object's state.
Teardown - Clean up resources.
Test lifecycle with mocks:
Setup data - Prepare object that is being tested.
Setup expectations - Prepare expectations in mock that is being used by primary object.
Exercise - Test the functionality.
Verify expectations - Verify that correct methods has been invoked in mock.
Verify state - Use asserts to check object's state.
Teardown - Clean up resources.
测试部分术语解释
单元测试期间, 被测单元会存在一些外部依赖的情况。
而单测中我们更加注重被测对象自身的功能和行为,以及与外部依赖的交互行为,比如是否调用,调用中参数,调用的次数和顺序以及返回的结果或发生的异常等,并不需要关注外部依赖的具体细节。
当然你页可以选择这两部分一起测试,可大声念一遍我们的术语:「单元测试」。这样是否已经和我们测试的原则相违背了,可缺失被测单元再缺失外部依赖的情况下,测试是不能正常进行的,我们陷入了两难境界,是否要继续遵守我们的原则?
为了让我们够能贯彻我们原则,出现了stub 和 mock 此类对象,其功能就是代替外部依赖,从而满足模拟真实场景,帮助我们的单元测试顺利进行。
那如何分辨那些是 stub 和 mock 呢?接下来们来辨析一下这两个概念。
Stub v.s Mock
相同目的
stub 和 mock 对象的出现,其作用都是代替外部依赖,帮助我们顺利进行单元测试。
不同生命周期
stub 和 mock 在测试的生命周期中表现不同,stub 协助被测单元进行自身的功能的校验,mock 更多是测试被测单元的行为是否符合预期,且自身在被测单元行为触发后进行验证。
看似说的比较玄乎,我们来看看对应不同类型下的代码段:
看代码 mock 好像比 stub 更加高级,因为 mock 可以再模拟真实环境下,协助被测单元进行测试自身功能,并且对于被测单元的对外部的行为同时进行测试,所以感觉是高级一些。
现状
实际情况下,我们编写的代码段更多是符合 stub 流程中的测试。可表现形式上,mock流程代码不是更高级吗?为什么现实使用中,我们并没有使用 mock 流程中的代码?
因为在通常情况下,我们使用的 mock 是退化的mock,从而是的 mock 流程和 stub 流程在测试使用上行为一致。其实我们是把 mock 当做了 stub 进行使用,其主要区别是 mock 创建时期就没有添加对应的后续期望,导致后期也用不着进行验证。就像这样:
为什么我们出现这样情况?很有可能是因为在日常使用中,我们对两者的概念边界都比较模糊,而且开发中经常涉及 mock 数据等术语,更容易干扰我们在单元测试语境下对 mock 的定义。所以在Jest社区中因为区分命名也进行过对应的讨论。Rename jest.mock to jest.stub
PS: 以上案例代码摘自参考文献。
参考文献
The text was updated successfully, but these errors were encountered: