Go单元测试工具gomonkey的使用

  目录

  Go 单元测试工具

  测试分为4个层次

  常犯的错误:

  单测的特征:

  单测

  代码 bug 总是在所难免, 越早发现问题解决成本越低, 单测可以尽早的暴露错误。提高代码之路,使得项目更高质量的交付。 起码有三个优点:

  编写单测是自测的一部分,编写新代码时增加相应的单测,可以帮助我们发现大部分的bug,有助于减少联调时的调整,提高联调效率。

  功能测试成本相对较高,因为经常需要执行一系列操作以验证结果是否符合预期。如果问题如果发现了问题,沟通和复测往往要花费很多的时间。

  回归测试是为了避免在对应用程序进行更改时引入bug。测试人员不仅要测试他们的新特性,还要测试以前存在的特性,以验证之前实现的特性是否仍然像预期的那样运行。 通过单元测试,可以在每次构建之后,重新运行整个测试流程,以确保新代码不会破坏已有功能

  一些异常的场景QA不好构造,比如并发出款是否资金安全,事务异常相关测试等等。而问题经常出现在这些异常的场景,可能引发线上问题甚至是事故。 而单元测试可通过mock的方式方便的模拟各种异常场景。

  Go 单元测试工具

  gomonkey

  引入 gomonkey 有如下好处:

  功能列表

  函数打桩, 对变量的 mock 实现原理跟 gostub 一样都是通过 reflect 包实现的。除了 mock 变量,gomonkey 还可以直接 mock 导出函数/方法、mock 代码所在包的非导出函数

  Go monkey Permission Denied 解决方案:https://github.com/eisenxp/macos-golink-wrapper

  mv $GOROOT/pkg/tool/darwin_amd64/link $GOROOT/pkg/tool/darwin_amd64/original_link

  cp https://github.com/eisenxp/macos-golink-wrapper/link $GOROOT/pkg/tool/darwin_amd64/link

  下载文件,然后再 cp

  wget https://raw.githubusercontent.com/eisenxp/macos-golink-wrapper/main/link

  gomonkey 提供了如下 mock 方法:

  gomonkey 打桩失败的可能原因

  goconvey

  为全局变量打一个桩

  package unittest

  import (

  "testing"

  "github.com/agiledragon/gomonkey"

  "github.com/smartystreets/goconvey/convey"

  )

  var num = 10 //全局变量

  func TestApplyGlobalVar(t *testing.T) {

  convey.Convey("TestApplyGlobalVar", t, func() {

  convey.Convey("change", func() {

  patches := gomonkey.ApplyGlobalVar(&num, 150)

  defer patches.Reset()

  convey.So(num, convey.ShouldEqual, 150)

  })

  convey.Convey("recover", func() {

  convey.So(num, convey.ShouldEqual, 10)

  })

  })

  }

  执行结果:

  === RUN TestApplyGlobalVar

  ..

  2 total assertions

  --- PASS: TestApplyGlobalVar (0.00s)

  PASS

  为一个函数打桩

  func networkCompute(a, b int) (int, error) {

  // do something in remote computer

  c := a + b

  return c, nil

  }

  func Compute(a, b int) (int, error) {

  sum, err := networkCompute(a, b)

  return sum, err

  }

  func TestFunc(t *testing.T) {

  // mock 了 networkCompute(),返回了计算结果2

  patches := gomonkey.ApplyFunc(networkCompute, func(a, b int) (int, error) {

  return 2, nil

  })

  defer patches.Reset()

  sum, err := Compute(1, 2)

  println("expected %v, got %v", 2, sum)

  if sum != 2 || err != nil {

  t.Errorf("expected %v, got %v", 2, sum)

  }

  }

  结果:

  === RUN TestFunc

  expected %v, got %v 2 3

  mock_func_test.go:91: expected 2, got 3

  --- FAIL: TestFunc (0.00s)

  FAIL

  可以看到上面的结果,执行时失败的, 没有成功。

  有时会遇到mock失效的情况,这个问题一般是内联导致的。

  什么是内联?

  为了减少函数调用时的堆栈等开销,对于简短的函数,会在编译时,直接内嵌调用的代码。

  我们禁用下内联,然后执行,

  执行结果:

  === RUN TestFunc

  expected %v, got %v 2 2

  --- PASS: TestFunc (0.00s)

  PASS

  对于 go 1.10以下版本,可使用-gcflags=-l禁用内联,对于go 1.10及以上版本,可以使用-gcflags=all=-l。但目前使用下来,都可以。 关于的用法,可以使用 查看 各参数含义

  到此这篇关于Go单元测试工具gomonkey的使用的文章就介绍到这了,更多相关Go gomonkey内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

  您可能感兴趣的文章: