You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何测试Go客户端调用外部API时的10秒超时逻辑是否正确生效

Go客户端超时场景测试方案

前置说明

首先先修正你代码里的两处笔误,避免运行出错:

  1. createRequest 函数末尾返回的变量应为 req,你当前写的 request 是未定义变量
  2. executeAuthorisationRequest 中打错误日志时,应该调用 requestError.Error(),不是 request.Error()

核心实现思路

不用依赖真实服务端,直接用Go标准库自带的net/http/httptest启动本地测试模拟服务端,在服务端的处理逻辑中加入超过10秒的等待,即可模拟响应过慢的场景,验证客户端超时逻辑是否生效。

具体测试实现步骤

1. (可选)优化业务代码可测试性

如果可以调整业务代码,建议把硬编码在executeAuthorisationRequest里的http.Client抽成参数传入,或者做成业务结构体的可配置字段,测试时可以把超时时间改小(比如改成100ms),不用真的等10秒就能跑完测试,大幅提升测试效率。
示例调整后的函数签名:

func executeAuthorisationRequest(request http.Request, client *http.Client) (*AuthorisationResponse, error) {
    // 原有逻辑,去掉内部创建client的代码
}

2. 编写测试用例

以下是完整的测试代码示例:

package yourpackage

import (
	"errors"
	"net"
	"net/http"
	"net/http/httptest"
	"net/url"
	"testing"
	"time"
)

func TestExecuteAuthorisationRequest_Timeout(t *testing.T) {
	// 启动本地模拟慢响应服务端
	slowServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// 服务端等待11秒,超过客户端设置的10秒超时阈值
		time.Sleep(11 * time.Second)
		// 超时后返回的内容不影响,因为客户端已经提前断开了
		w.WriteHeader(http.StatusOK)
		_, _ = w.Write([]byte(`{"status":"ok"}`))
	}))
	defer slowServer.Close()

	// 构造测试请求
	testBody := url.Values{}
	testBody.Set("test_key", "test_value")
	req, err := creatRequest(slowServer.URL, testBody)
	if err != nil {
		t.Fatalf("构造测试请求失败: %v", err)
	}

	// 执行业务方法并统计耗时
	startTime := time.Now()
	_, err = executeAuthorisationRequest(*req)
	costTime := time.Since(startTime)

	// 验证结果
	// 1. 必须返回错误
	if err == nil {
		t.Fatal("预期返回超时错误,实际未返回任何错误")
	}
	// 2. 错误必须是超时类型错误
	var netErr net.Error
	if !errors.As(err, &netErr) || !netErr.Timeout() {
		t.Fatalf("预期返回超时错误,实际错误为: %v", err)
	}
	// 3. 耗时符合10秒左右的预期,允许1秒以内的误差
	if costTime < 9*time.Second || costTime > 11*time.Second {
		t.Fatalf("超时耗时不符合预期,实际耗时: %v", costTime)
	}
}

3. 测试运行说明

直接执行go test -run TestExecuteAuthorisationRequest_Timeout -v即可运行该测试用例,不需要任何外部依赖。如果改了超时配置为短时间,测试运行速度会更快。

注意事项

  • 不要通过匹配错误字符串的方式判断是否是超时错误,用标准库的errors.As断言为net.Error后调用Timeout()方法判断是最稳定的方式,不会因为Go版本迭代或者底层实现变更导致测试失效。
  • 如果你的代码中有其他链路的超时设置(比如传输层、TLS握手超时等),要确保这些超时的阈值大于10秒,避免其他环节的超时干扰测试结果。

内容的提问来源于stack exchange,提问作者TypeScriptProgrammer1234

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 08:36:03