0

0

Go如何测试网络请求_HTTP测试基本方法

P粉602998670

P粉602998670

发布时间:2026-01-19 13:17:02

|

400人浏览过

|

来源于php中文网

原创

Go中用httptest.Server模拟HTTP服务可实现可靠、快速、稳定的单元测试,通过内存服务器验证请求参数、响应状态码与Body,需defer server.Close()防泄漏,并结合ServeMux、超时控制、错误响应等覆盖边界场景。

go如何测试网络请求_http测试基本方法

Go中用httptest.Server模拟HTTP服务

直接调用真实API做单元测试不可靠、慢、易失败,Go标准库提供httptest.Server在内存中启动一个临时HTTP服务,专为测试设计。

  • 它返回一个运行中的*httptest.Server,其URL字段可直接用于http.Gethttp.Client.Do
  • 必须在测试结束前调用server.Close(),否则端口不释放、goroutine泄漏
  • 适合验证请求是否发出、参数是否正确、响应状态码/Body是否符合预期
func TestMyClient(t *testing.T) {
    server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        if r.URL.Path != "/api/data" {
            t.Errorf("expected /api/data, got %s", r.URL.Path)
        }
        if r.Method != "GET" {
            t.Errorf("expected GET, got %s", r.Method)
        }
        w.WriteHeader(http.StatusOK)
        w.Write([]byte(`{"id":123}`))
    }))
    defer server.Close() // 关键:必须defer
client := &http.Client{}
resp, err := client.Get(server.URL + "/api/data")
if err != nil {
    t.Fatal(err)
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
    t.Errorf("expected 200, got %d", resp.StatusCode)
}

}

http.ServeMuxhttp.Handler控制路由行为

单个httptest.Server默认只支持一个http.HandlerFunc。若需多路径(如/health/users),应使用http.ServeMux或自定义http.Handler

  • http.ServeMux支持Handle/HandleFunc注册多个路由,更贴近真实服务器结构
  • 避免在HandlerFunc里硬编码逻辑分支(如if r.URL.Path == ...),不易维护且难覆盖边界情况
  • 注意:ServeMux不支持通配符或正则,复杂路由需用第三方库(如gorilla/mux)或自行实现ServeHTTP
func TestMultiPathClient(t *testing.T) {
    mux := http.NewServeMux()
    mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
        w.WriteHeader(http.StatusOK)
        w.Write([]byte("ok"))
    })
    mux.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "application/json")
        w.WriteHeader(http.StatusCreated)
        w.Write([]byte(`[{"id":1,"name":"alice"}]`))
    })
server := httptest.NewUnstartedServer(mux)
server.Start()
defer server.Close()

// 测试 /health
resp, _ := http.Get(server.URL + "/health")
// 测试 /users
resp2, _ := http.Post(server.URL+"/users", "application/json", nil)

}

测试超时、重试、错误响应等边界场景

真实网络请求会遇到连接拒绝、超时、5xx响应等,仅测200 OK远远不够。关键在于控制http.Client行为,而非依赖服务端返回。

家电小商城网站源码1.0
家电小商城网站源码1.0

家电公司网站源码是一个以米拓为核心进行开发的家电商城网站模板,程序采用metinfo5.3.9 UTF8进行编码,软件包含完整栏目与数据。安装方法:解压上传到空间,访问域名进行安装,安装好后,到后台-安全与效率-数据备份还原,恢复好数据后到设置-基本信息和外观-电脑把网站名称什么的改为自己的即可。默认后台账号:admin 密码:132456注意:如本地测试中127.0.0.1无法正常使用,请换成l

下载
  • &http.Client{Timeout: 10 * time.Millisecond}触发超时,验证客户端是否妥善处理context.DeadlineExceeded
  • httptest.NewUnstartedServer启动后不调用Start(),再发起请求,可模拟“连接被拒绝”
  • 在Handler中写http.Error(w, "bad request", http.StatusBadRequest),测试客户端对非2xx的容错逻辑
  • 不要用time.Sleep等待,而应通过server.Close()后立即发请求来制造失败
func TestClientTimeout(t *testing.T) {
    server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        time.Sleep(100 * time.Millisecond) // 故意延迟
        w.WriteHeader(http.StatusOK)
    }))
    defer server.Close()
client := &http.Client{
    Timeout: 50 * time.Millisecond,
}

_, err := client.Get(server.URL + "/slow")
if !errors.Is(err, context.DeadlineExceeded) {
    t.Fatalf("expected timeout error, got %v", err)
}

}

避免常见陷阱:全局变量、未关闭Body、忽略重定向

测试中容易因疏忽引入隐性失败,这些点高频出问题且难定位。

  • 别在测试函数外定义http.Client或复用httptest.Server——并发测试会冲突,每个测试应独占资源
  • 每次resp.Body必须Close(),否则文件描述符泄漏,大量测试后可能报too many open files
  • http.DefaultClient默认启用重定向(CheckRedirect),若被测逻辑依赖302跳转但没显式处理,测试可能意外成功或失败;建议显式构造Client并设CheckRedirect: func(req *http.Request, via []*http.Request) error { return http.ErrUseLastResponse }
  • io.ReadAll(resp.Body)读取完整Body,别只读前几个字节,否则后续读取为空

测试HTTP客户端的核心不是“能不能通”,而是“行为是否可控、边界是否覆盖、资源是否干净”。真正难的从来不是起一个test server,而是让每一个http.Client配置、每一条错误路径、每一次Body读取都落在你的掌控之中。

相关专题

更多
if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

751

2023.08.22

scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

187

2023.10.18

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

288

2023.10.25

全局变量怎么定义
全局变量怎么定义

本专题整合了全局变量相关内容,阅读专题下面的文章了解更多详细内容。

78

2025.09.18

python 全局变量
python 全局变量

本专题整合了python中全局变量定义相关教程,阅读专题下面的文章了解更多详细内容。

96

2025.09.18

http500解决方法
http500解决方法

http500解决方法有检查服务器日志、检查代码错误、检查服务器配置、检查文件和目录权限、检查资源不足、更新软件版本、重启服务器或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

365

2023.11.09

http请求415错误怎么解决
http请求415错误怎么解决

解决方法:1、检查请求头中的Content-Type;2、检查请求体中的数据格式;3、使用适当的编码格式;4、使用适当的请求方法;5、检查服务器端的支持情况。更多http请求415错误怎么解决的相关内容,可以阅读下面的文章。

410

2023.11.14

HTTP 503错误解决方法
HTTP 503错误解决方法

HTTP 503错误表示服务器暂时无法处理请求。想了解更多http错误代码的相关内容,可以阅读本专题下面的文章。

1925

2024.03.12

PS使用蒙版相关教程
PS使用蒙版相关教程

本专题整合了ps使用蒙版相关教程,阅读专题下面的文章了解更多详细内容。

23

2026.01.19

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WEB前端教程【HTML5+CSS3+JS】
WEB前端教程【HTML5+CSS3+JS】

共101课时 | 8.4万人学习

JS进阶与BootStrap学习
JS进阶与BootStrap学习

共39课时 | 3.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号