• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

Go单元测试:为什么stub叫做桩函数,mock叫做模拟接口?

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

 

一、前言介绍:

对于我们平时开发的业务代码,单个函数往往不是独立的,它需要依赖于其他模块、第三方库、数据库、消息交互的结果等等。

对于这种代码做单元测试,就会变得复杂许多,而对于当前要测试的函数来说,这些被依赖的其他函数,无非就是返回不同的数据而已。所以在做单元测试的时候,我们只需要让这些被依赖的其他函数返回我们期望的数据,就可以继续测试我们当前需要测试的函数。

对于上面这种外部依赖的情况,我们往往采用两种办法来解决,一种是Mock(模拟),一种是Stub(桩)。我们可以通过模拟这些外部依赖的异常行为(例如:数据库不可访问,http消息返回失败),进而控制被测试的函数走那些分支。

在知道了stub和mock存在的原因之后,我们就需要进一步的研究stub和mock了。

首先,我们需要知道它们是什么?其次,我们需要知道它们有什么区别?

Mock:是模拟的意思,指的是在测试包中创建一个结构体,满足某个外部依赖的接口 interface{}。

Stub:   是桩的意思,指的是在测试包中创建一个模拟方法,用于替换生成代码中的方法。

二、例子

这些例子比较简单,都只是为了演示mock和stub的使用。

1. mock例子:

mock 的做法是创建一个struct,然后实现所需要接口中的函数,在测试的时候,将调用的接口替换成测试mock出来的struct就可以了。

mock采用的替换,是替换整个接口的方式(备注:接口可以是入参,也可以是struct中的变量,不过都需要在测试之前,替换完成)。

例子如下:

GetType函数原本是根据不同的入参yu,多不同的操作,加、减和赋值为零。

在mock之后,指定GetType类型只做一种操作 “加法”。

Output:

通过输出可以看出,mock之前的是三种操作,mock替换之后变成了一种操作加法。

2. stub例子:

使用stub做单元测试的话,代码是侵入式的,需要将对应的函数做成回调函数的方式,以方便后续的测试代码可以将这个函数替换成,测试希望指定的功能实现。

例子如下:(备注:这个例子比较简单,只是为了演示stub的使用。)

GetType函数原本是根据不同的入参,多不同的操作,加、减和赋值为零。

在Stub之后,指定GetType类型只做一种操作 加法。

Output:

打桩之前:功能函数会根据入参的数值,来做不同的操作,输出不同的结果,分别是 :取0;做加法:2+5 = 7;做减法:5-1 = 4。

打桩之后:桩函数StubFunc只返回一种操作“加法”,所以测试用例不管入参的类型是什么,都是按照加法来操作,分别是:1+3 = 4;2+5 = 7; 5+1 = 6;

三、mock与stub的比较

1)mock和stub都是采用替换的方式来实现,被测试的函数中的依赖关系,不过mock采用的是接口替换的方式,stub采用的是函数替代的方式。

2)mock的实现对功能代码没有侵入性,stub的侵入性比较强,在实现功能函数的时候,就需要为了测试设置一些回调函数,也就是这里所谓的桩。

3)对于控制被替代的方法来讲,mock如果想支持不同的输出,就需要提前实现不同的分支代码,甚至需要定义不同的mock结构体来实现,这样的mock代码会变成一个支持所有逻辑分支的一个最大集合,mock代码复杂性会变高;stub却能很好的控制桩函数的不同分支,因为stub替换的是函数,那么只要需要再用到这种输出的时候,定义一个函数即可,而这个函数甚至都可以是匿名函数。

基于上面的分析,我们可以设计一种方式,让stub和mock结合起来,例子如下:

被测试代码与mock例子中的一致,mock的代码中新增了回调函数和是否使用回调函数2个变量,在测试用例中,通过实现不同的stub函数来控制桩函数的输出结果。

Output:

从测试用例运行的结果来看,在stub函数是“加法”的时候,前两个用例,都会执行“加法”操作;在stub是“减法”的时候,最后一个用例会执行“减法”操作。

小结:通过上面的三个例子来看,mock和stub各有优缺点,而mock和stub的结合,是一种很不错的实践方式,不过最终使用那种方式去设计测试用例,还取决于具体的场景。(备注:Google提供了一个专门的gomock来给单元测试使用,这个会在后续章节介绍。)


公众号:灰子学技术,欢迎大家关注、评论、探讨


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
go笔记2发布时间:2022-07-10
下一篇:
go-ipfs命令详解之bootstrap发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap