gomonkey用户如何对桩计数

问题的由来

gomonkey 社区,用户 JiangHanChao 提了一个 issue,如下图所示:

issue-82.png

恰巧,笔者身边的同事和朋友也有咨询过该问题,因此就想着写篇短文来统一回复。

解决方案

gomonkey 在实现打桩功能时,仅在函数头植入了几行汇编,再增加一个计数功能的话,对某些简短的函数打桩后会破坏下一个函数的序言,进而造成运行时段错误,并且这个错误没法在打桩时就发现并告知用户。

基于上述考虑,gomonkey 对桩计数不能在框架层面统一解决,可以考虑在用户侧来解决,即在测试代码中定义桩计数器结构体,每个测试开始时初始化该结构体,每个测试结束前断言该结构体中的字段。

典型案例

issue-82 中给出的示例作为典型案例,供大家参考!

(1)产品代码保持不变

package moduleA

func FuncA() error {
    return nil
}

func FuncB() error {
    return nil
}

func FuncC() error {
    if err := FuncA(); err != nil {
        return err
    }

    if err := FuncB(); err != nil {
        return err
    }

    return nil
}

(2)在测试代码中应用本文解决方案

package moduleA

import (
    "errors"
    "testing"

    . "github.com/agiledragon/gomonkey/v2"
    . "github.com/smartystreets/goconvey/convey"
)

// 在测试代码中定义桩计数器结构体
type monkeyMetric struct {
    callFuncATimes int
    callFuncBTimes int
}

func TestFuncC(t *testing.T) {
    // 每个测试开始时初始化该结构体
    var metric monkeyMetric
    err := errors.New("test")
    Convey("test", t, func() {
        patches := ApplyFunc(FuncA, func() error {
            metric.callFuncATimes++
            return err
        })
        patches.ApplyFunc(FuncB, func() error {
            metric.callFuncBTimes++
            return err
        })
        defer patches.Reset()

        e := FuncC()
        So(e, ShouldEqual, err)
        // 每个测试结束前断言该结构体中的字段
        So(metric.callFuncATimes, ShouldEqual, 1)
        So(metric.callFuncBTimes, ShouldEqual, 1)
    })
}

(3)执行该测试用例,结果符合预期
测试用例执行结果:

=== RUN   TestFuncC

  test ✔✔✘


Failures:

  * /Users/zhangxiaolong/Desktop/D/go-workspace/gomonkey/test/module_a_test.go
  Line 33:
  Expected: '1'
  Actual:   '0'
  (Should be equal)

用户在 issue-82 中的期望:

user-expect.png

小结

用户期望可以在框架层面解决一切共性问题,这本属于合理的诉求,但现实有时很骨感,在种种约束下必须改变思路,而在用户侧较优雅的解决相关问题也是一种不错的选择。

本文针对 gomonkey 用户,给出了如何对桩进行计数的解决方案,并提供了典型案例,希望对读者有一定的帮助!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 117,493评论 1 238
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 50,995评论 1 200
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 72,556评论 0 167
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 35,638评论 0 127
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 42,431评论 1 204
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 35,209评论 1 124
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 27,191评论 2 206
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 26,329评论 0 119
  • 想象着我的养父在大火中拼命挣扎,窒息,最后皮肤化为焦炭。我心中就已经是抑制不住地欢快,这就叫做以其人之道,还治其人...
    爱写小说的胖达阅读 25,285评论 5 170
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 29,341评论 0 177
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 26,593评论 1 167
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 27,820评论 1 175
  • 白月光回国,霸总把我这个替身辞退。还一脸阴沉的警告我。[不要出现在思思面前, 不然我有一百种方法让你生不如死。]我...
    爱写小说的胖达阅读 22,171评论 0 24
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 24,773评论 2 163
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 28,606评论 3 172
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 23,581评论 0 4
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 23,673评论 0 113
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 29,792评论 2 187
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 30,225评论 2 188

推荐阅读更多精彩内容