## Unit Test Rules
编写单元测试时,必须遵守以下规则:
1. **目录、包名、用例名**:
- 测试文件和被测文件在同一目录下,package 名相同。命令规范{sourceFileName}_test.go
- 用例名采用 given_when_then 风格
2. **依赖库**:统一使用以下三个库进行 mock 和断言:
- `"testing"` — 标准测试框架
- `. "github.com/smartystreets/goconvey/convey"` — BDD 风格断言
- `"github.com/agiledragon/gomonkey/v2"` — 函数/方法 mock
3. **Convey 层级**:每个测试函数内部最多两层 `Convey` 嵌套,即一个 function 内只允许 `Convey` → `Convey` 两级。
func TestExample(t *testing.T) {
Convey("Given 一个服务实例", t, func() {
// 第一层:准备公共数据
Convey("When 调用成功", func() {
patches := gomonkey.NewPatches()
defer patches.Reset()
// 打桩...
So(result, ShouldEqual, expected)
})
Convey("When 调用失败", func() {
patches := gomonkey.NewPatches()
defer patches.Reset()
// 不同打桩...
So(err, ShouldNotBeNil)
})
})
}
4. **Patch 隔离**:每个 `Convey` 用例使用独立的 `gomonkey.NewPatches()`,不同用例之间 patch 互不干扰。在 `Convey` 内使用 `defer patches.Reset()` 确保用例结束后清理。
5. **覆盖率**:保证被测代码 100% 被覆盖,包括所有分支、错误路径和边界条件。
6. **特殊组件的mock**:
k8sClient = testUtils.MyClientForTest{}
logger := zapLogger.Sugar()
7. **避免事项**:
- 避免对map的值,进行So判断,因为运行时 map 的 hash 和迭代顺序不确定