GO UT
参考如下golang ut写法 -- convey框架 + gomonkey 框架:
func TestEnvCheck(t *testing.T) {
Convey("test EnvCheck", t, func() {
zapLogger, _ := zap.NewProduction()
logger := zapLogger.Sugar()
patches := gomonkey.NewPatches()
param := EnvCheckParamInfo{
StreamNo: "envCheck_111",
MaterIp: "gdb-manager-test.gdb",
IAPort: "8021",
RdbPasswd: "*****",
ApiType: "https",
}
Convey("test 1: envCheck success", func() {
defer patches.Reset()
patches.ApplyFunc(agentConfig.LocalExecutionCommand, func(request agentConfig.CmdExecRequest) agentConfig.CmdExecResult {
return agentConfig.CmdExecResult{ReturnCode: agentConfig.TaskSuccessCode}
})
_, err := EnvCheck(param, logger)
So(err, ShouldBeNil)
})
Convey("test 2: envCheck failed", func() {
defer patches.Reset()
patches.ApplyFunc(agentConfig.LocalExecutionCommand, func(request agentConfig.CmdExecRequest) agentConfig.CmdExecResult {
return agentConfig.CmdExecResult{ReturnCode: agentConfig.TaskFailCode, ErrorMsg: "test error"}
})
_, err := EnvCheck(param, logger)
So(err, ShouldNotBeNil)
})
})
}
对如下文件写ut:
1. 两层convey结构
2. 针对os.ReadFile 进行mock,返回测试需要的数据
package agentApis
import (
"Operator/cmd/operator-agent/app/agentConfig"
"time"
)
// OperatorAgentTask 表示OperatorAgent要执行的任务
type OperatorAgentTask struct {
TaskID string `json:"taskID"` // 任务ID
TaskType agentConfig.AgentTask `json:"taskType"` // 任务类型
TaskParam interface{} `json:"taskParam"` // 任务参数
}
// AgentTaskResult OperatorAgent任务结果
type AgentTaskResult struct {
TaskID string `json:"taskID"` // 任务ID,格式taskType_timestamp
TaskType agentConfig.AgentTask `json:"taskType"` // 任务类型
TaskParam interface{} `json:"taskParam"` // 任务参数
TaskCode int `json:"taskCode"` // 任务返回码,0成功,2失败, 1任务ID不存在
TaskStatus string `json:"taskStatus"` // 任务状态:进行中、成功或失败
TaskResult interface{} `json:"taskResult"` // 任务结果
ErrorMsg string `json:"errorMsg"` // 任务报错
StartTime time.Time `json:"startTime"` // 任务起始时间
EndTime time.Time `json:"endTime"` // 任务结束时间
}
package cacheUtils
import (
"Operator/cmd/operator-agent/app/agentApis"
"Operator/cmd/operator-agent/app/agentConfig"
gdberrors "Operator/pkg/utils/errors"
"context"
"encoding/json"
"fmt"
"go.uber.org/zap"
"os"
"path/filepath"
"sync"
"time"
)
type FileCache struct {
mu sync.RWMutex
TaskResults map[string]*agentApis.AgentTaskResult // 缓存
logger *zap.SugaredLogger // 日志
filePath string
}
// recoverFromFile 从本地json文件读取
func (f *FileCache) recoverFromFile() error {
if f.filePath == "" {
return nil
}
f.mu.Lock()
defer f.mu.Unlock()
data, err := os.ReadFile(f.filePath)
if err != nil {
return err
}
var tempCache map[string]*agentApis.AgentTaskResult
if err := json.Unmarshal(data, &tempCache); err != nil {
return gdberrors.NewBaseError(gdberrors.JsonErr, fmt.Sprintf("parse json error %v", err))
}
for taskId, taskInfo := range tempCache {
f.logger.Infof("[recoverFromFile] taskId %v", taskId)
if taskInfo.TaskStatus == agentConfig.TaskProcessStatus {
taskInfo.TaskStatus = agentConfig.TaskFailedStatus
taskInfo.ErrorMsg = "Pod异常退出,任务中断"
taskInfo.EndTime = time.Time{}
}
}
f.TaskResults = tempCache
return nil
}
要求:
- 两层 Convey 结构:
外层:test saveToFileLocked
内层:10个不同的测试场景
- 使用 gomonkey mock 多个基础函数:
os.Stat - 模拟目录检查
os.MkdirAll - 模拟目录创建
json.MarshalIndent - 模拟 JSON 序列化
os.WriteFile - 模拟文件写入
os.Rename - 模拟文件重命名
...
- 覆盖多种测试场景:
空文件路径
目录不存在且创建成功
目录不存在且创建失败
目录检查出错(非"不存在"错误)
JSON 序列化失败
文件写入失败
文件重命名失败
正常保存(复杂数据)
...

浙公网安备 33010602011771号