程序员的测试课
郑晔
开源项目 Moco 作者
18911 人已学习
新⼈⾸单¥59
登录后,你可以任选2讲全文学习
课程目录
已完结/共 23 讲
加餐 (1讲)
结束语 (1讲)
程序员的测试课
15
15
1.0x
00:00/00:00
登录|注册

07 | Mock 框架:怎么让测试变得可控?

你好,我是郑晔!
上一讲,我们谈到测试不好测,关键是软件设计问题。一个好的设计可以把很多实现细节从业务代码中隔离出去。
之所以要隔离出去,一个重要的原因就是这些实现细节不那么可控。比如,如果我们依赖了数据库,就需要保证这个数据库环境同时只有一个测试在用。理论上这样不是不可能,但成本会非常高。再比如,如果依赖了第三方服务,那么我们就没法控制它给我们返回预期的值。这样一来,很多出错的场景,我们可能都没法测试。
所以,在测试里,我们不能依赖于这些好不容易隔离出去的细节。否则,测试就会变得不稳定,这也是很多团队测试难做的重要原因。不依赖于这些细节,那我们的测试总需要有一个实现出现在所需组件的位置上吧?或许你已经想到答案了,没错,这就是我们这一讲要讲的 Mock 框架。

从模式到框架

做测试,本质上就是在一个可控的环境下对被测系统 / 组件进行各种试探。拥有大量依赖于第三方代码,最大的问题就是不可控。
怎么把不可控变成可控?第一步自然是隔离,第二步就是用一个可控的组件代替不可控的组件。换言之,用一个假的组件代替真的组件。
这种用假组件代替真组件的做法,在测试中屡见不鲜,几乎成了标准的做法。但是,因为各种做法又有细微的差别,所以,如果你去了解这个具体做法会看到很多不同的名词,比如:Stub、Dummy、Fake、Spy、Mock 等等。实话说,你今天问我这些名词的差异,我也需要去查找相关的资料,不能给出一个立即的答复。它们之间确实存在差异,但差异几乎到了可以忽略不计的份上。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Mock框架:让测试变得更可控 本文深入介绍了Mock框架的基本原理和使用方法,旨在帮助读者了解如何通过Mock框架解决测试中的不可控因素,使得测试变得更加可控和稳定。作者首先强调了良好的软件设计对测试的重要性,指出好的设计可以将实现细节从业务代码中隔离出去,提高测试的可控性。在此基础上,Mock框架的作用得以突出,它能够使用可控的组件代替不可控的组件,从而提高测试的可控性。 文章详细介绍了Mock框架的基本逻辑和使用方法,以Mockito框架为例进行讲解。重点强调了设置模拟对象和校验对象行为的重要性,包括如何创建模拟对象、设置模拟对象的行为以及校验对象行为是否符合预期。此外,还介绍了Mock框架的发展历程和在Java社区中的应用情况。 另外,文章还提到了Mock框架的延伸,即模拟服务器的应用。通过Moco框架的示例,展示了如何模拟HTTP服务器和WebSocket服务器,进一步延伸了Mock框架的应用范围。 总的来说,本文通过通俗易懂的方式,帮助读者快速了解Mock框架的核心概念和使用方法,强调了Mock框架在测试中的重要作用,以及其在解决测试不可控因素方面的价值。文章内容丰富,适合技术人员阅读,能够帮助他们更好地理解和应用Mock框架。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《程序员的测试课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(12)

  • 最新
  • 精选
  • sylan215
    1、这一讲主要是讲 Mock 的,对于自动化测试来说,这个技术确实很关键,当然,老师也在文中建议慎用,使用的前提是,我们真的明白这些技术的作用和副作用。 2、前一讲说了测试要减少耦合性,同时我们为了保证测试目的的唯一性,就引入了 Mock 技术,它一定程度上,让我们的关注点更集中; 3、和 Mock 技术类似,我们还可以了解 Stub、Dummy、Fake、Spy 等技术,同样是帮忙我们优化测试目的,简化测试实现的; 4、Mock 等模拟对象,可以让我们方便的模拟传参和不同返回值的情况,这些如果是在实际业务环境中,构造起来可能会非常麻烦; 5、非测试目的的过程中的 verify 要慎用,避免降低用例的适用性,也会增加用例的维护成本; 以上,期待后续的精彩内容。

    作者回复: 多谢你的总结!

    2021-08-18
    7
  • return
    请教一下老师, 把第三方mock掉了, 那么如何验证 我们请求第三方的参数是否正确, 我们到第三方的请求是否可以正常运行。

    作者回复: 严格地说,第三方是否正常运行,这事不属于测试。如果采用测试的方式,第三方服务有一天宕机了,你的测试失败了,但你根本就没有动代码。所以,它无法起到测试应有的作用。所以,你真正需要的是一个监控程序,而不是一个测试。 当然,为了让人们注意到第三方服务的正确性,你专门做一个“测试”集合,在持续集成的服务以更长的周期运行,而不需要像普通的测试一样,每次提交都运行。

    2021-08-20
    4
    5
  • 阿姆斯壮
    今天又忍不住上来分享一下。把郑大之前的课程应用到工作之后。先从「坏味道」入手,利用函数式编程消除大量重复代码。不做CVS程序员。当工作和学习充分结合起来后,发现每天的工作都充满了乐趣。总感觉工作时间好快。(一天7个小时)不需要加班。可能我们公司是一个不务正业的IT公司。接下来,就是期待郑大的测试课。把自动化测试这块也应用到工作中。

    作者回复: 加油,向高水平程序员进军!

    2021-08-18
    5
  • byemoto
    如果存在多层, 那么每层对下层依赖的对象都需要做Stub/Mock吗? 比如AggregateService依赖多个Service对象, 而各个Service对象又有自己的Repository, 那么在测试AggregateService时, 需要对各个Service对象做Mock吗?

    作者回复: 按照你的逻辑,测试这个聚合服务就是要对其依赖的服务做Mock。这和单独的服务是否依赖于Repository没关系

    2021-08-18
    2
    4
  • 下弦の月
    是否可以这么理解? 有个待测的组件A,内部依赖组建B,会执行B.callFunc(); 同时,B还依赖于组建C,会执行 C.callMethod(); 对A做单元测试的时候,我们需要隔离对B的依赖。Stub 做的事情是模拟一个B对象,设置好模拟B对象的 callFunc() 这个方法的输入与输出即可。 而Mock,除了上述的安排好输入与输出之外,还要对B.callFunc() 这个方法本身的行为做校验。比如verify(C,atLeast(1)).callMethod(any()); 总结下来就是:如果只是准备一个被模拟对象的输入输出,就是Stub;如果要检查被模拟对象内部的行为,就是Mock。

    作者回复: 你这个理解没问题

    2021-08-18
    4
    4
  • asusual
    以前写测试基本都写了verify。现在看来郑大的观点非常准确~ 过度使用 verify,在写代码的时候,你会有一种成就感。但是,一旦涉及代码修改,整个人就不好了。因为实现细节被 verify 锁定死,一旦修改代码,这些 verify 就很容易造成测试无法通过。

    作者回复: 所谓经验,都是教训

    2021-08-22
    3
  • MHT
    请教一下老师:假如我需要对A方法做单测,A方法调用B方法,B方法又会调用C方法,其中C的行为是不可控的,我在做mock的时候,是要mock B还是C呢?
    2023-06-15归属地:广东
  • 6点无痛早起学习的和尚
    Moco 主要模拟服务器,那突然想到 http 调用第三方服务器,都是在一个封装调用类里,那直接用 mock 框架,mock 这个类是不是也可以完成同样的事情
    2023-04-28归属地:北京
  • 一打七
    老师好,【测试应该测试的是接口行为,而不是内部实现】这句怎么理解?测试不就是测试业务的实现逻辑吗?这里怎么又说不是
    2023-02-10归属地:北京
    1
  • ifelse
    使用 Mock 框架,少用 verify。--记下来
    2022-06-08
收起评论
显示
设置
留言
12
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部