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 这些函数/方法。
相关推荐
学习编程的gas1 小时前
C++面向对象编程入门:从类与对象说起(一)
开发语言·c++
冼紫菜1 小时前
【Spring Boot 多模块项目】@MapperScan失效、MapperScannerConfigurer 报错终极解决方案
java·开发语言·mybatis
还听珊瑚海吗2 小时前
基于SpringBoot的抽奖系统测试报告
java·spring boot·后端
Bear on Toilet2 小时前
Bug日记——实现“日期类”
开发语言·c++·bug
apcipot_rain2 小时前
《面向对象程序设计-C++》实验五 虚函数的使用及抽象类
开发语言·c++
明月看潮生4 小时前
青少年编程与数学 02-019 Rust 编程基础 05课题、复合数据类型
开发语言·青少年编程·rust·编程与数学
幼稚诠释青春4 小时前
Java学习笔记(对象)
java·开发语言
你怎么知道我是队长4 小时前
Go语言标识符
后端·golang
Wyc724095 小时前
JDBC:java与数据库连接,Maven,MyBatis
java·开发语言·数据库
强化学习与机器人控制仿真5 小时前
Newton GPU 机器人仿真器入门教程(零)— NVIDIA、DeepMind、Disney 联合推出
开发语言·人工智能·python·stm32·深度学习·机器人·自动驾驶