美文网首页
gomonkey用户如何对桩计数

gomonkey用户如何对桩计数

作者: _张晓龙_ | 来源:发表于2022-08-04 23:15 被阅读0次

    问题的由来

    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 用户,给出了如何对桩进行计数的解决方案,并提供了典型案例,希望对读者有一定的帮助!

    相关文章

      网友评论

          本文标题:gomonkey用户如何对桩计数

          本文链接:https://www.haomeiwen.com/subject/chvcwrtx.html