Golang泛型Mock库gs-mock发布:类型安全的模拟测试工具
Golang泛型Mock库gs-mock发布:类型安全的模拟测试工具 大家好 :waving_hand:,
我想分享一个我一直在做的项目:gs-mock —— 一个现代的、类型安全的 Go 模拟库,完全支持泛型。
为什么需要另一个模拟库?
传统的 Go 模拟工具通常:
- 严重依赖反射,导致运行时类型错误。
- 需要冗长的设置代码。
- 未能充分利用 Go 1.18+ 的泛型特性。
gs-mock 通过提供编译时安全性和更简洁的 API 来解决这些问题。
:sparkles: 主要特性
- 类型安全:使用 Go 泛型构建,确保没有运行时意外。
- 多种模拟模式:
Handle:直接处理函数调用。When/Return:有条件地返回结果。
- 灵活的匹配:支持最多 5 个参数和 5 个返回值。
- 上下文集成:与
context.Context无缝协作。 - 自动重置:使用
Manager.Reset()轻松重置所有模拟。 - 清晰的错误信息:当模拟缺失或重复时,提供详细的 panic 信息。
:rocket: 快速示例
type Repository[T any] interface {
FindByID(id string) (T, error)
}
// 生成的模拟:RepositoryMockImpl[T]
func TestRepositoryMock(t *testing.T) {
repo := NewRepositoryMockImpl[int](gsmock.NewManager())
// 当没有注册模拟时,预期会发生 panic
assert.Panic(t, func() {
_, _ = repo.FindByID("1")
}, "no mock code matched")
// 注册行为
repo.MockFindByID().Handle(func(id string) (int, error) {
return 42, nil
})
v, err := repo.FindByID("1")
assert.Nil(t, err)
assert.Equal(t, v, 42)
}
:gear: 安装
gs-mock 附带一个代码生成工具:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/go-spring/gs/HEAD/install.sh)"
然后在你的代码中:
//go:generate gs mock -o service_mock.go
:open_file_folder: GitHub
:backhand_index_pointing_right: https://github.com/go-spring/gs-mock
我非常欢迎反馈、贡献和实际测试报告。 如果你发现任何缺失的功能,请随时提出问题或提交 PR!
谢谢!
更多关于Golang泛型Mock库gs-mock发布:类型安全的模拟测试工具的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于Golang泛型Mock库gs-mock发布:类型安全的模拟测试工具的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
gs-mock 看起来是一个很有前景的 Go 泛型 Mock 库,它确实解决了传统反射-based 模拟库的一些痛点。以下是一个更深入的技术示例,展示其类型安全和泛型能力:
// 定义泛型接口
type Cache[T any] interface {
Get(key string) (T, bool)
Set(key string, value T)
Delete(key string) error
}
// 使用 gs-mock 生成的模拟代码
func TestCacheMock(t *testing.T) {
mgr := gsmock.NewManager()
cache := NewCacheMockImpl[string](mgr)
// 类型安全的模拟设置
cache.MockGet().
When(gsmock.Eq("user:1")).
Return("John Doe", true)
cache.MockGet().
When(gsmock.Eq("user:2")).
Return("", false)
// 编译时类型检查
value, found := cache.Get("user:1")
assert.Equal(t, "John Doe", value)
assert.True(t, found)
// 处理函数模拟
cache.MockDelete().Handle(func(key string) error {
if key == "protected" {
return errors.New("cannot delete protected key")
}
return nil
})
err := cache.Delete("protected")
assert.Error(t, err)
// 重置所有模拟
mgr.Reset()
}
关键优势:
- 编译时类型安全:泛型确保模拟方法签名与接口完全匹配
- 清晰的 API 设计:
When/Return模式提供直观的测试设置 - 上下文支持:内置
context.Context处理
// 上下文示例
type Service interface {
Process(ctx context.Context, data []byte) (int, error)
}
func TestServiceWithContext(t *testing.T) {
svc := NewServiceMockImpl(gsmock.NewManager())
svc.MockProcess().Handle(func(ctx context.Context, data []byte) (int, error) {
if ctx.Err() != nil {
return 0, ctx.Err()
}
return len(data), nil
})
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
result, err := svc.Process(ctx, []byte("test"))
assert.Equal(t, 4, result)
assert.Nil(t, err)
}
这个库的泛型实现确实为 Go 测试带来了更类型安全的方式,减少了运行时错误的风险。

