在 GoConvey (github.com/smartystreets/goconvey/convey
)中,ApplyFunc
和 ApplyMethod
都用于 mock(模拟)函数或方法,主要区别在于它们的作用对象不同:
函数 | 作用对象 | 用途 |
---|---|---|
ApplyFunc |
普通函数 | Mock 一个全局函数或包级函数 |
ApplyMethod |
结构体方法 | Mock 某个结构体的实例方法 |
1️⃣ ApplyFunc
用于 Mock 普通函数
ApplyFunc
用于替换**包级函数(普通全局函数)**的实现,例如:
go
package main
import (
"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 某个结构体实例的方法,例如:
go
package main
import (
"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 这些函数/方法。