go test 的内联问题
使用
monkey
对函数进行打桩单测的时候,发现打桩函数没有生效。
习惯直接使用IDE的可视化的run
和debug
功能进行跑单测,没有关注到具体执行的命令。
单测代码
func TestLogin(t *testing.T) {
// 初始化 dao 层
userDao := &daoUser.UserDao{}
// 初始化 service 层
entity := &LoginService{}
Convey("GetUserByUsername", t, func() {
Convey("Should be success", func() {
// 给 GetByUsername 函数打桩,指定返回值
patches := ApplyMethod(reflect.TypeOf(UserDao), "GetByUsername",
func(*daoUser.UserDao, string) (*daoUser.User, error) {
return &daoUser.User{
ID: 1,
Username: "weirwei",
Password: "123456",
}, nil
})
defer patches.Reset()
// 测试 Login
res, err := entity.Login("weirwei", "123456")
// 断言
So(err, ShouldBeNil)
So(res, ShouldBeTrue)
})
})
}
问题分析
查看run
和debug
的命令
# run
/usr/local/go/bin/go test -c -o /private/var/folders/1q/llslx_n95d1brs7hq2drxjjw0000gn/T/___1go_test_gin_study_service_svUser gin-study/service/svUser
# debug
/usr/local/go/bin/go test -c -o /private/var/folders/1q/llslx_n95d1brs7hq2drxjjw0000gn/T/___go_test_gin_study_service_svUser -gcflags all=-N -l gin-study/service/svUser
很明显就能发现debug
比run
多了 -gcflags all=-N -l
,这个就是==禁用内联==的选项
内联(inlining):粗暴的来说,就是将函数内容复制到函数调用的地方,==减少了函数调用的开支==,但一定程度上会增加程序的代码量,==占用更多的内存==。
这么看就很明显了,本来打桩后 GetUserByUsername
会直接返回给定的结果,不走 dao 层的实际代码,但是 go 在编译过程中会进行内联优化,将 dao 层的代码直接“复制”过来,绕过了测试桩。而在本段测试代码中并没有对 dao 层进行相关配置及初始化,导致代码在执行时出现错误。