golang编写UT:applyFunc和applyMethod区别

GoConveygithub.com/smartystreets/goconvey/convey)中,ApplyFuncApplyMethod 都用于 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 某个结构体的实例方法

🚀 什么时候用?

  • 当你在 单元测试 里,需要 隔离依赖的外部函数方法 ,避免真实逻辑执行,或者控制返回值 时,可以使用 ApplyFuncApplyMethod 来 Mock 这些函数/方法。
相关推荐
醇氧2 小时前
【Windows】优雅启动:解析一个 Java 服务的后台启动脚本
java·开发语言·windows
古城小栈3 小时前
Docker 多阶段构建:Go_Java 镜像瘦身运动
java·docker·golang
华仔啊3 小时前
这 10 个 MySQL 高级用法,让你的代码又快又好看
后端·mysql
MapGIS技术支持3 小时前
MapGIS Objects Java计算一个三维点到平面的距离
java·开发语言·平面·制图·mapgis
码事漫谈3 小时前
国产时序数据库崛起:金仓凭什么在复杂场景中碾压InfluxDB
后端
上进小菜猪3 小时前
当时序数据不再“只是时间”:金仓数据库如何在复杂场景中拉开与 InfluxDB 的差距
后端
程序员zgh3 小时前
C++ 互斥锁、读写锁、原子操作、条件变量
c语言·开发语言·jvm·c++
小灰灰搞电子4 小时前
Qt 重写QRadioButton实现动态radioButton源码分享
开发语言·qt·命令模式
by__csdn4 小时前
Vue3 setup()函数终极攻略:从入门到精通
开发语言·前端·javascript·vue.js·性能优化·typescript·ecmascript
喵了meme4 小时前
C语言实战5
c语言·开发语言