如何在Golang中测试网络请求错误处理_模拟异常响应场景

10次阅读

Go 测试网络错误需用 MockHTTPClient 模拟异常,如超时、连接拒绝、5xx 状态码、空 body、JSON 解析失败等,通过自定义 RoundTripper 或 httptest.Server 精确控制响应,并断言具体错误类型确保覆盖边界。

如何在 Golang 中测试网络请求错误处理_模拟异常响应场景

在 Go 中测试网络请求的错误处理,关键在于绕过真实 HTTP 客户端,用 http.ClientTransport 字段或直接替换 http.DefaultClient,注入可控的异常响应(如超时、连接拒绝、5xx 状态码 、空 body、JSON 解析失败等)。不需要启动真实服务,也不依赖外部环境。

用自定义 RoundTripper 模拟各种 HTTP 异常

实现 http.RoundTripper 接口,可精确控制每次请求的行为。适合模拟:连接超时、TLS 握手失败、无响应、返回非 2xx 状态码、body 读取中断等。

  • 返回 net.ErrClosed 或自定义 error 模拟连接被拒或中断
  • time.AfterFunc 延迟 panic 或关闭 response.Body 模拟读取超时
  • 构造 &http.Response{StatusCode: 503, Body: io.NopCloser(strings.NewReader(""))} 返回服务不可用
  • 返回 Body 是一个在 Read() 时返回 io.EOFio.ErrUnexpectedEOF 的 mock reader,触发 JSON 解析失败

用 httptest.Server + 主动中断模拟服务端异常

httptest.NewUnstartedServer 创建服务后不调用 .Start(),再用普通 client 请求它,会立即返回 dial tcp [::1]:xxxx: connect: connection refused —— 这是最贴近真实“服务未启动”的场景。

  • 启动 server 后手动 srv.Close(),再发请求,复现“连接已关闭”
  • 在 handler 中写入 header 后主动 panicreturn,让 response 不完整,触发客户端解析异常
  • handler 中用 time.Sleep(3 * time.Second) 配合 client 设置 Timeout: 1 * time.Second,精准触发超时

封装可配置的 MockClient 便于复用

避免每个测试都重写 RoundTripper,可定义结构体如:

立即学习 go 语言免费学习笔记(深入)”;

type MockHTTPClient struct {StatusCode int     Body       string     Err        error     Delay      time.Duration}

它的 RoundTrip(*http.Request) (*http.Response, error) 方法根据字段返回对应结果。测试中只需:

client := &http.Client{Transport: &MockHTTPClient{StatusCode: 500, Body: `{"error":"server"}`}, } // 注入到被测对象(如 service.DoRequest(……))

验证错误路径是否真正覆盖边界情况

不要只检查 err != nil,要断言错误类型和内容:

  • errors.Is(err, context.DeadlineExceeded) 区分超时与其它错误
  • json.Unmarshal 失败,检查 errors.As(err, &json.SyntaxError{})
  • 当底层返回 net.OpError,用 errors.Is(err, syscall.ECONNREFUSED)errors.Is(err, context.Canceled)
  • 确保你的业务错误包装逻辑(如 fmt.Errorf("fetch user: %w", err))没吞掉底层关键信息

text=ZqhQzanResources