Fiber框架单元测试应使用app.Test()而非go test起HTTP服务,因其绕过网络栈、避免端口冲突与资源泄漏,并支持伪造请求头和上下文;需注意c.Status()不自动写响应头,必须配合c.Send()或c.JSON()才能正确返回状态码。

Fiber框架的单元测试不依赖go test跑HTTP服务,而是用fiber.New()构造测试用App,直接调用app.Test()发起请求。它绕过网络栈、不启动监听端口,速度快、隔离性好,适合验证路由逻辑、中间件行为和JSON响应结构。
为什么不能直接用go test起服务再发HTTP请求
这么做看似直观,但会引入三类干扰:
- 本地端口冲突或
too many open files(尤其并行测试时) -
testing.T生命周期短,http.Server可能来不及关就退出,导致资源泄漏 - 无法控制请求上下文(如伪造
Authorization头、模拟ctx.UserContext())
正确做法是把Fiber应用当成普通Go对象来测——它本身不绑定端口,app.Test()内部用net/http/httptest模拟请求生命周期。
app.Test()怎么构造请求并断言
关键点在于:传入*http.Request,接收*http.Response,手动读取Body和Status。常见组合如下:
- GET请求:
req, _ := http.NewRequest("GET", "/api/users", nil) - POST + JSON:
req, _ := http.NewRequest("POST", "/login", strings.NewReader(`{"user":"a","pass":"b"}`)),别忘了设req.Header.Set("Content-Type", "application/json") - 带Header或Query参数:
req.URL.RawQuery = "page=2"或req.Header.Set("X-Trace-ID", "test123") - 断言状态码:
assert.Equal(t, 200, resp.StatusCode) - 读取JSON响应:
json.NewDecoder(resp.Body).Decode(&data),再检查data.ID等字段
中间件和依赖注入怎么测
Fiber的中间件链在app.Test()中默认生效,但部分依赖(如数据库连接、JWT验证)需手动“打桩”:
- 若Handler里用了
c.Locals("db"),测试前先req = req.WithContext(context.WithValue(req.Context(), fiber.Ctx{}.Context().Value("db"), mockDB)) - JWT中间件常依赖
c.Get("Authorization"),直接req.Header.Set("Authorization", "Bearer xxx")即可绕过签名校验 - 避免在测试中初始化真实DB连接——用
mock库或内存Map替代,否则测试变慢且不可靠
最易被忽略的是:Fiber的c.Status()不会自动写响应头,若你只调用c.Status(401)没跟c.Send()或c.JSON(),resp.StatusCode仍是200。务必检查Handler是否真正输出了响应。


















