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

在 Go 中测试网络请求的错误处理,关键在于绕过真实 HTTP 客户端,用 http.Client 的 Transport 字段或直接替换 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.EOF或io.ErrUnexpectedEOF的 mock reader,触发 JSON 解析失败
用 httptest.Server + 主动中断模拟服务端异常
httptest.NewUnstartedServer 创建服务后不调用 .Start(),再用普通 client 请求它,会立即返回 dial tcp [::1]:xxxx: connect: connection refused —— 这是最贴近真实“服务未启动”的场景。
- 启动 server 后手动
srv.Close(),再发请求,复现“连接已关闭” - 在 handler 中写入 header 后主动
panic或return,让 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))没吞掉底层关键信息










