测试Go错误处理需验证函数在异常输入下是否返回预期错误,并检查调用方正确响应;2. 使用errors.New创建的预定义错误可通过==比较,适用于包级变量;3. Go 1.13后推荐用fmt.Errorf搭配%w包装错误,利用errors.Is判断是否等于目标错误(支持链式匹配),errors.As判断错误链中是否存在指定类型;4. 对于外部依赖如数据库或网络调用,应通过接口抽象并注入返回错误的mock实现来触发错误路径;5. 综合构造错误输入、使用errors.Is/As及mock技术可有效覆盖多数实际场景中的错误处理逻辑测试。

在Go语言中测试错误处理逻辑是确保程序健壮性的关键部分。重点在于验证函数在异常输入或失败场景下是否返回预期的错误,并且调用方能正确响应这些错误。
使用标准库中的 errors 包进行错误比对
Go中很多函数通过返回 error 类型来表示失败。测试时,你可以检查返回的 error 是否与预期一致。
对于预定义错误(如使用 errors.New 创建),可以直接比较:
- 使用 == 比较错误值是否相等
- 注意:仅适用于包级变量错误,不适用于动态生成的错误
// 示例:定义一个可能出错的函数func divide(a, b float64) (float64, error) { if b == 0 { return 0, errors.New("division by zero") } return a / b, nil}// 测试除零错误func TestDivideByZero(t *testing.T) { _, err := divide(1, 0) if err == nil { t.Fatal("expected error, got nil") } if err.Error() != "division by zero" { t.Errorf("expected 'division by zero', got '%s'", err.Error()) }}
使用 errors.Is 和 errors.As 进行更灵活的错误判断
从 Go 1.13 开始,推荐使用 fmt.Errorf 配合 %w 包装错误,并利用 errors.Is 或 errors.As 进行断言。
立即学习“go语言免费学习笔记(深入)”;
-
errors.Is(err, target) 判断 err 是否等于目标错误(支持包装链)
-
errors.As(err, &target) 判断 err 链中是否存在指定类型的错误
// 示例:包装错误var ErrNotFound = errors.New("not found")func getData(id string) (string, error) { if id == "" { return "", fmt.Errorf("invalid id: %w", ErrNotFound) } // ...}func TestGetData_ErrorWrapped(t *testing.T) { _, err := getData("") if !errors.Is(err, ErrNotFound) { t.Errorf("expected error to wrap ErrNotFound") }}
模拟外部依赖以触发错误路径
真实项目中错误常来自数据库、网络请求等。可通过接口抽象并注入模拟实现来触发错误。
- 定义数据访问接口
- 编写一个总是返回错误的 mock 实现
- 在测试中传入该 mock
type DB interface { FetchUser(id string) (*User, error)}type MockDB struct { Err error}func (m *MockDB) FetchUser(id string) (*User, error) { return nil, m.Err}func TestUserService_GetUser_Error(t *testing.T) { mockDB := &MockDB{Err: errors.New("db failed")} svc := UserService{DB: mockDB} _, err := svc.GetUser("123") if err == nil { t.Fatal("expected error from DB") }}
基本上就这些。关键是构造能产生错误的输入或环境,然后检查返回的 error 是否符合预期。结合 errors.Is/As 和 mock 技术,可以覆盖大多数实际场景。
以上就是如何在Golang中测试错误处理逻辑的详细内容,更多请关注php中文网其它相关文章!