(由部门研发同学投稿)
在macbook开发机本地IDE执行 某模块单元测试的过程中,由于一些通用mock框架在macbook 11/12版本无法执行,导致部分逻辑难以覆盖。
在使用了 "github.com/bytedance/mockey" 后,解决了 mock 框架无法适配 mac 系统的问题,此模块 单元测试整体覆盖率已达到90%。
本文旨在分享 mockey 框架的使用方法,并与业内使用广泛的 gomonkey 框架进行对比。
业务代码,从redis中查询xxx缓存并解析成标准格式的业务代码逻辑,如下:
// XxxCache 缓存结构
type XxxCache struct {
Advertiser string
TaTagId []int64
}
// GetxxxCache 获取 rta 缓存
func GetXxxCache(oneId string) []*RtaCache {
var xxxCaches []*XxxCache
cache, err := RedisQuery(id)
if err != nil {
return xxxCaches
}
/*
若干业务逻辑
*/
}
return xxxCaches
}
// RedisQuery 查询 redis
func RedisQuery(id string) (map[string]string, error) {
var data map[string]string
/*
若干业务逻辑
*/
return data, nil
}
现分别给出使用mockey和gomonkey两种框架的单元测试方法:
mockey + mockey 封装的PatchConvey
func TestGetXxxCache_Mockey(t *testing.T) {
PatchConvey("TestGetXxxCache", t, func() {
PatchConvey("query redis err", func() {
Mock(RedisQuery).Return(nil, errors.New("mock redis query err")).Build()
data, err := GetXxxCache("1111")
So(err, ShouldNotBeNil)
So(err.Error(), ShouldEqual, "mock redis query err")
So(data, ShouldBeNil)
})
PatchConvey("query redis success", func() {
Mock(RedisQuery).Return(map[string]string{
"ad1": "1,2,3,4",
"ad2": "1,a,b",
}, nil).Build()
data, err := GetXxxCache("1111")
So(err, ShouldBeNil)
So(data, ShouldNotBeNil)
So(len(data), ShouldEqual, 2)
...
})
})
}
gomonkey + convey
func TestGetXxxCache_GoMonkey(t *testing.T) {
Convey("TestGetXxxCache", t, func() {
Convey("RedisQuery err", func() {
patches := gomonkey.ApplyFunc(RedisQuery, func(id string) (map[string]string, error) {
return nil, errors.New("mocked RedisQuery error")
})
defer patches.Reset()
xxxCaches, err := GetXxxCache("1111")
So(err, ShouldNotBeNil)
So(err.Error(),ShouldEqual,"mocked RedisQuery error")
})
Convey("query redis success", func() {
patches := gomonkey.ApplyFunc(RedisQuery, func(id string) (map[string]string, error) {
return map[string]string{"ad1": "1,2,3,4", "ad2": "1,a,b"}, nil
})
defer patches.Reset()
data, err := GetXxxCache("1111")
So(err, ShouldBeNil)
So(data, ShouldNotBeNil)
})
})
}
对比
总得来说,推荐使用mockey框架进行 mock。无论是从 mock 代码的编写,mock 代码的可读性,使用的便捷性,mockey 都要优于 gomonkey。
| bytedance/mockey | agiledragon/gomonkey |
|---|---|
| mac 本地可执行 | 需要获取较高系统权限,在比如macos 10.5+无法执行 |
| 无需Reset,每个 mock 的生命周期为当前的PatchConvey | 需要显式 defer patch.Reset() |
| mock 简单,函数名 + Return + Build | mock 较繁琐,需要输入mock 对象对应的 func |
更多信息请查看官方文档
mockey库:github.com/bytedance/m…
gomonkey库:github.com/agiledragon…
总结
以上是我在公司宣传的单测系列的第二期内容,它是对第一期的延续。你还记得我们第一期内容最后同事提出的问题吗?由于我们公司的开发主要使用 Macbook 11/12 芯片,使用 GoMonkey 的项目在本地的 Mac 上无法正常运行。这个问题导致了需要进行模拟的代码无法编写单元测试覆盖。
为了解决这个问题,团队成员进行了调研和比较,最终决定采用 Mockey 库。由负责该模块的同学推动,该模块的单元测试覆盖率已经达到了90%的高水平👏👏。这位同学将整个过程进行了总结,并投稿给了质量文化宣传团队,希望与大家分享这次的经验。
后续的每一期内容我都会及时发布在掘金的工程师质量文化专栏,欢迎大家关注,共同进步。
最后,照例给大家看下我们在公司张贴的海报吧~