你是否在移动端开发中遇到过依赖外部服务难以
测试的问题?本文将介绍如何使用GoMock(Go语言的Mocking框架)为iOS和
Android项目中的Go后端代码创建模拟对象,解决测试依赖问题,提升测试效率。读完本文后,你将能够掌握GoMock的基本使用方法,并将其应用到移动端项目的测试中。
项目简介
GoMock是Go语言的一个Mocking框架,它与Go内置的testing包集成良好,也可用于其他场景。项目路径为gh_mirrors/moc/mock,更多信息可参考README.md。
安装GoMock
在开始使用GoMock之前,需要先安装mockgen工具。
环境要求
·Go语言环境(已安装并配置好GOPATH)
· 将$GOPATH/bin添加到PATH中
安装命令
根据Go版本选择以下命令进行安装:
Go版本 < 1.16
GO111MODULE=on go get github.com/golang/mock/mockgen@v1.6.0
Go 1.16+
go install github.com/golang/mock/mockgen@v1.6.0
mockgen工具使用
mockgen有两种操作模式:source模式和reflect模式。
Source模式
Source模式从源文件生成模拟接口,通过-source标志启用。
示例:
mockgen -source=foo.go [other options]
Reflect模式
Reflect模式通过构建一个使用反射来理解接口的程序生成模拟接口,通过传递两个非标志参数启用:导入路径和逗号分隔的符号列表。
示例:
mockgen database/sql/driver Conn,Driver
# 便于`go:generate`使用
mockgen . Conn,Driver
常用标志
-destination: 指定生成代码的输出文件路径
-package: 指定生成代码的包名
-imports: 指定生成代码中需要的显式导入
-mock_names: 为生成的模拟指定自定义名称
在移动端项目中使用GoMock
基本示例:构建Mocks
假设我们有一个如下的接口需要测试:
type Foo interface {
Bar(x int) int
}
func SUT(f Foo) {
// ...
}
使用GoMock编写测试:
func TestFoo(t *testing.T) {
ctrl := gomock.NewController(t)
// 断言Bar()被调用
defer ctrl.Finish()
m := NewMockFoo(ctrl)
// 断言对Bar()的第一次且唯一一次调用传入99,其他情况将失败
m.
EXPECT().
Bar(gomock.Eq(99)).
Return(101)
SUT(m)
}
如果使用Go 1.14+和mockgen 1.5.0+,并将*testing.T传递给gomock.NewController(t),则无需显式调用ctrl.Finish(),它将通过自注册的Cleanup函数自动调用。
构建Stubs
func TestFoo(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
m := NewMockFoo(ctrl)
// 不做任何断言。当Bar以99调用时执行匿名函数并返回结果
m.
EXPECT().
Bar(gomock.Eq(99)).
DoAndReturn(func(_ int) int {
time.Sleep(1*time.Second)
return 101
}).
AnyTimes()
// 不做任何断言。当Bar以101调用时返回103
m.
EXPECT().
Bar(gomock.Eq(101)).
Return(103).
AnyTimes()
SUT(m)
}
修改失败消息
修改Want值
Want值来自匹配器的String()方法,可以通过以下方式修改:
gomock.WantFormatter(
gomock.StringerFunc(func() string { return "is equal to fifteen" }),
gomock.Eq(15),
)
修改Got值
Got值来自对象的String()方法,可以通过以下方式修改:
gomock.GotFormatterAdapter(
gomock.GotFormatterFunc(func(i interface{}) string {
// 前导0
return fmt.Sprintf("%02d", i)
}),
gomock.Eq(15),
)
项目结构与相关文件
·核心代码目录:gomock/
call.go
controller.go
matchers.go
· 示例代码目录:sample/
user.go
user_test.go
· 测试相关目录:mockgen/internal/tests/
调试常见错误
reflect vendoring error
当使用reflect模式和依赖项 vendoring 时遇到此错误,有以下三种解决方法:
使用source模式
添加空导入import _ "github.com/golang/mock/mockgen/model"
在mockgen命令中添加--build_flags=--mod=mod
总结
GoMock为Go语言项目提供了强大的Mocking功能,能够有效解决移动端项目中Go后端代码的测试依赖问题。通过本文介绍的安装、使用方法和示例,你可以开始在iOS/Android项目中应用GoMock进行测试,提高代码质量和测试效率。
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理