go 单元测试(二)mock

2022-08-20  本文已影响0人  wayyyy

当待测试的函数/对象的依赖关系很复杂,并且有些依赖不能直接创建,例如数据库连接、文件I/O等。这种场景就非常适合使用 mock/stub 测试。简单来说,就是用 mock 对象模拟依赖项的行为。

gomock

gomock 是官方提供的mock框架,同时还提供了mockgen工具用来辅助申城测试代码:
首先使用如下命令安装:

go get -u github.com/golang/mock/gomock
go get -u github.com/golang/mock/mockgen

然后再使用如下命令生成,

# mockgen -source=[源文件] -destination=[生成后的mock文件] -package=[包名]

会将源文件的接口生成mock对象。


gomonkey 库

试用了官方的,发现要先生成文件等很麻烦,搜索得到可以使用 gomonkey 这个库来mock对象。

gomonkey 提供了如下 mock 方法:

但是有2点需要注意:

gomonkey 有多个版本,我们可以使用最新的v2版本

github.com/agiledragon/gomonkey/v2
mock全局变量
var num = 10

func TestApplyGlobalVar(t *testing.T) {
    patches := gomonkey.ApplyGlobalVar(&num, 150)
    defer patches.Reset()

    assert.Equal(t, num, 150)
}
mock 函数
import (
    "github.com/agiledragon/gomonkey/v2"
    "github.com/stretchr/testify/assert"
    "testing"
)

func networkCompute(a, b int) (int, error) {
    // 假设这里依赖于其他远程服务
    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
    })
    // v2 还可以直接使用:
    //patches := gomonkey.ApplyFuncReturn(networkCompute, 2, nil)

    defer patches.Reset()

    sum, err := Compute(1, 2)
    assert.Equal(t, err, nil)
    assert.Equal(t, sum, 2)
}

这里有时候会打桩失败,原因是因为函数内联导致的。

mock 方法
type Task struct {
}

func (t *Task) Sub(a, b int) int {
    return a - b
}

func (t *Task) add(a, b int) int {
    return a + b
}

方法:

func TestTask_Run(t *testing.T) {
    task := &Task{}
    patches := gomonkey.ApplyMethod(task, "Sub", func(a, b int) int {
        return a + b
    })
    //patches := gomonkey.ApplyMethodReturn(task, "Sub",4)
    defer patches.Reset()

    result := task.Sub(3, 2)
    assert.Equal(t, result, 5)
}

私有方法:

func TestTask_add(t *testing.T) {
    task := &Task{}
    patches := gomonkey.ApplyPrivateMethod(task, "add", func(_ *Task, a, b int) int {
        return a * b
    })
    defer patches.Reset()

    result := task.add(3, 2)
    assert.Equal(t, result, 6)
}

参考资料
1、https://www.jianshu.com/p/25d49af216b7

上一篇下一篇

猜你喜欢

热点阅读