如何在Golang中测试HTTP客户端_模拟外部API请求响应

15次阅读

go测试http客户端应优先拦截传输层而非真实发请求,推荐用httptest.Server伪造服务端验证请求构造与响应处理,或用httpmock模拟多场景响应,也可手动替换Client.Transport实现轻量控制。

如何在Golang中测试HTTP客户端_模拟外部API请求响应

在 Go 中测试 HTTP 客户端,关键不是真的发请求,而是替换掉默认的 http.Client 的传输层(Transport),用 httpmock标准库httptest.Server 拦截并返回预设响应。

用 httptest.Server 伪造服务端(推荐用于集成/端到端风格)

适合验证客户端逻辑是否正确构造请求、处理状态码jsON 响应等,不依赖第三方库。

  • 启动一个临时 HTTP 服务,返回你想要的响应体、状态码、Header
  • 把客户端的 BaseURL 指向这个本地 server.URL
  • 测试完记得调用 server.Close()

示例:

func TestMyClient_GetUser(t *testing.T) {     server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {         if r.Method != "GET" || r.URL.Path != "/users/123" {             t.Fatal("unexpected request")         }         w.Header().Set("Content-Type", "application/json")         w.WriteHeader(http.StatusOK)         json.NewEncoder(w).Encode(map[string]interface{}{"id": 123, "name": "Alice"})     }))     defer server.Close()      client := NewAPIClient(server.URL) // 把 server.URL 当作 API 地址传入     user, err := client.GetUser(context.Background(), "123")     if err != nil {         t.Fatal(err)     }     if user.Name != "Alice" {         t.Error("expected Alice")     } }

用 httpmock 模拟特定请求(适合单元测试、更轻量)

当你要覆盖多种响应场景(如 404、超时、网络错误)且不想启 HTTP 服务时,httpmock 更灵活。

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

  • 导入 github.com/jarcoal/httpmock
  • 在测试开始前调用 httpmock.Activate(),结束时 DeactivateAndReset()
  • httpmock.RegisterResponder() 匹配方法 + URL,返回自定义响应

示例:

func TestMyClient_GetUser_WithHttpMock(t *testing.T) {     httpmock.Activate()     defer httpmock.DeactivateAndReset()      httpmock.RegisterResponder("GET", "https://api.example.com/users/456",         httpmock.NewStringResponder(200, `{"id":456,"name":"Bob"}`))      client := NewAPIClient("https://api.example.com")     user, err := client.GetUser(context.Background(), "456")     if err != nil {         t.Fatal(err)     }     if user.Name != "Bob" {         t.Error("expected Bob")     } }

替换 Client.Transport 手动拦截(纯标准库,无依赖)

如果你只想最小化依赖,可直接给 http.Client 设置自定义 Transport,实现 RoundTrip 方法。

  • 写一个满足 http.RoundTripper 接口结构体
  • RoundTrip 里检查 *http.Request,按需返回 *http.Response
  • 注意:要手动构造 Body(比如用 io.NopCloser(strings.NewReader(...))

适用场景:学习原理、极简环境、或需要深度控制底层行为。

别忘了测试错误路径

真实调用中,网络失败、JSON 解析失败、HTTP 状态码非 2xx 都很常见。测试时要覆盖:

  • 模拟 500 响应,检查是否返回 error
  • 返回非法 JSON,验证解码是否出错
  • httpmock.RegisterResponder 返回空 body 或超长 body
  • 对 client 设置 Timeout,再用慢响应验证超时逻辑

不复杂但容易忽略。

text=ZqhQzanResources