在 GoConvey(github.com/smartystreets/goconvey/convey
)中,ApplyFunc
和 ApplyMethod
都用于 mock(模拟)函数或方法,主要区别在于它们的作用对象不同:
函数 | 作用对象 | 用途 |
---|---|---|
ApplyFunc | 普通函数 | Mock 一个全局函数或包级函数 |
ApplyMethod | 结构体方法 | Mock 某个结构体的实例方法 |
1️⃣ ApplyFunc
用于 Mock 普通函数
ApplyFunc
用于替换**包级函数(普通全局函数)**的实现,例如:
package mainimport ("fmt""testing". "github.com/smartystreets/goconvey/convey""github.com/smartystreets/goconvey/convey/gomock"
)// 目标函数
func GetData() string {return "Real Data"
}func TestApplyFunc(t *testing.T) {Convey("Mock GetData function", t, func() {// Mock GetData,使其返回 "Mocked Data"reset := gomock.ApplyFunc(GetData, func() string {return "Mocked Data"})defer reset() // 确保测试结束后恢复原函数So(GetData(), ShouldEqual, "Mocked Data") // 断言函数返回值})
}
🔹 原理:ApplyFunc(GetData, mockImplementation)
拦截了 GetData
函数的调用,并让它返回 "Mocked Data"
。
2️⃣ ApplyMethod
用于 Mock 结构体方法
ApplyMethod
用于 mock 某个结构体实例的方法,例如:
package mainimport ("testing". "github.com/smartystreets/goconvey/convey""github.com/smartystreets/goconvey/convey/gomock"
)// 结构体
type UserService struct{}func (u *UserService) GetUserName() string {return "Real User"
}func TestApplyMethod(t *testing.T) {Convey("Mock UserService.GetUserName method", t, func() {// Mock 结构体的 GetUserName 方法reset := gomock.ApplyMethod((*UserService)(nil), "GetUserName", func(_ *UserService) string {return "Mocked User"})defer reset() // 确保测试结束后恢复原方法service := &UserService{}So(service.GetUserName(), ShouldEqual, "Mocked User") // 断言方法返回值})
}
🔹 原理:
ApplyMethod((*UserService)(nil), "GetUserName", mockImplementation)
拦截了 所有UserService
实例的GetUserName
方法,使其返回"Mocked User"
。
🎯 总结
方法 | Mock 目标 | 使用示例 |
---|---|---|
ApplyFunc | 普通函数 | ApplyFunc(GetData, mockFunc) |
ApplyMethod | 结构体方法 | ApplyMethod((*UserService)(nil), "MethodName", mockFunc) |
ApplyFunc
适用于:Mock 全局函数ApplyMethod
适用于:Mock 某个结构体的实例方法
🚀 什么时候用?
- 当你在 单元测试 里,需要 隔离依赖的外部函数 或 方法,避免真实逻辑执行,或者控制返回值时,可以使用
ApplyFunc
或ApplyMethod
来 Mock 这些函数/方法。