跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

怎样测试Golang的HTTP服务 使用httptest包模拟请求

使用 httptest 可以在不启动真实服务器的情况下测试 go 的 http 服务,通过构造请求、捕获响应、断言结果三步完成测试;2. httptest.newrequest 创建模拟请求,httptest.newrecorder 记录响应,直接调用 处理器 函数进行测试;3. 可测试不同场景如参数缺失或不同 http 方法;4. 若使用 http.servemux,可通过 mux.servehttp 测试路由匹配;5. 运行 go test -v 执行测试并验证结果,确保处理器行为正确。 在 Go 中测试 HTTP 服务时,
net/http/httptest
包是非常有用的工具。它允许你模拟 HTTP 请求和响应,而无需真正启动网络服务,从而实现快速、可靠的单元测试。 下面是如何使用
httptest
测试一个简单的 Golang HTTP 服务的完整示例。 1. 编写一个简单的 HTTP 服务 假设我们有一个处理
/hello
路由的简单服务: 立即学习 “ go语言免费学习笔记(深入) ”;
// main.go package main import ( "fmt" "net/http" ) func helloHandler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello, %s!", r.URL.Query().Get("name")) }
我们注册这个处理器:
func main() { http.HandleFunc("/hello", helloHandler) http.ListenAndServe(":8080", nil) }
2. 使用
httptest
编写测试 我们为
helloHandler
编写测试,验证它是否正确返回响应。 vue.js + axios.js图片压缩处理并上传到服务器 vue.js + axios.js图片压缩处理并上传到服务器 下载
// main_test.go package main import ( "net/http" "net/http/httptest" "testing" ) func TestHelloHandler(t *testing.T) { // 创建一个请求 req := httptest.NewRequest("GET", "/hello?name=Gopher", nil) // 创建一个响应记录器 w := httptest.NewRecorder() // 调用处理器 helloHandler(w, req) // 获取响应 resp := w.Result() defer resp.Body.Close() // 检查状态码 if resp.StatusCode != http.StatusOK { t.Errorf("期望状态码 %d,实际得到 %d", http.StatusOK, resp.StatusCode) } // 检查响应体 expected := "Hello, Gopher!" if body := w.Body.String(); body != expected { t.Errorf("期望响应体 %q,实际得到 %q", expected, body) } }
3. 关键组件说明
httptest.NewRequest(method, url, body)
创建一个模拟的 HTTP 请求。第三个参数是请求体(如 POST 数据),如果是 GET 可以传
nil
。
httptest.NewRecorder()
返回一个
*httptest.ResponseRecorder
,它实现了
http.ResponseWriter
接口,可以记录响应的状态码、头信息和响应体,便于后续断言。 直接调用 handler 因为 Go 的处理器是函数,可以直接传入
w
和
req
进行调用,不需要启动服务器。 4. 测试其他场景 你可以轻松测试各种情况,比如参数缺失、不同 HTTP 方法等。
func TestHelloHandler_NoName(t *testing.T) { req := httptest.NewRequest("GET", "/hello", nil) w := httptest.NewRecorder() helloHandler(w, req) expected := "Hello, !" if body := w.Body.String(); body != expected { t.Errorf("期望 %q,实际 %q", expected, body) } }
5. 测试路由(使用
http.ServeMux
) 如果你使用了
ServeMux
,也可以测试路由是否正确匹配:
func TestRouter(t *testing.T) { mux := http.NewServeMux() mux.HandleFunc("/hello", helloHandler) req := httptest.NewRequest("GET", "/hello?name=World", nil) w := httptest.NewRecorder() mux.ServeHTTP(w, req) if w.Code != http.StatusOK { t.Errorf("期望状态码 %d,实际 %d", http.StatusOK, w.Code) } expected := "Hello, World!" if w.Body.String() != expected { t.Errorf("期望 %q,实际 %q", expected, w.Body.String()) } }
6. 运行测试 在项目目录下运行:
go test -v
你应该看到类似输出:
=== RUN TestHelloHandler --- PASS: TestHelloHandler (0.00s) === RUN TestHelloHandler_NoName --- PASS: TestHelloHandler_NoName (0.00s) PASS ok your-module-name 0.001s
基本上就这些。使用
httptest
可以让你的 HTTP 处理器测试变得简单、快速且可重复,避免依赖真实网络环境。关键是构造请求、捕获响应、断言结果三步。

相关文章