必须用 app.Test() 而非 http.Get,因其是 Fiber 内存级测试入口,跳过 TCP 层、不监听端口、无网络依赖;http.Get 会引发 DNS 解析、端口冲突等 CI 不稳定问题。

直接用 app.Test(),别启动真实服务,也别用 http.Get —— 否则测的不是逻辑,是端口和竞态。
为什么必须用 app.Test() 而不是 http.Get
因为 app.Test() 是 Fiber 官方提供的内存级测试入口,它跳过 TCP 层、不监听端口、不依赖网络,整个请求生命周期在 goroutine 内同步走完。而 http.Get 会触发真实 HTTP 客户端,引入 DNS 解析、连接建立、TIME_WAIT、端口冲突等不可控因素——尤其在 CI 并行跑多个测试时,connection refused 或 address already in use 是常态。
常见错误现象:
- 本地能过,CI 随机失败
- 测试函数卡住,最后超时
- 改一个路由,所有测试全挂(其实是端口被前一个 test 残留占着)
性能影响:每次 http.Get 至少多花 10–50ms;app.Test() 通常在 0.1–2ms 内完成。
app.Test() 前必须做完的三件事
新手最常漏掉 setup 步骤,导致 404 或中间件不生效:
- 调用
setupRoutes(app)或手动注册所有路由(Fiber 不反射扫描,app.Get()必须显式执行) - 注册中间件:如
app.Use(logger.New())、app.Use(recover.New()),否则 panic 不被捕获、日志不输出 - 确保
app是已初始化的*fiber.App实例,不是刚fiber.New()出来的空壳
错误示例:app := fiber.New(); resp, _ := app.Test(req) → 一定 404,因为没注册任何路由。
POST/JSON 接口测试必须设 Content-Type 和 Body 格式
Fiber 的 ctx.BodyParser() 和 ctx.JSON() 强依赖请求头和 Body 类型。漏掉任一环节,解析就静默失败(字段保持零值,无报错)。
正确写法:
req, _ := http.NewRequest("POST", "/user", bytes.NewReader([]byte(`{"name":"alice"}`)))
req.Header.Set("Content-Type", "application/json")
resp, _ := app.Test(req)
关键点:
-
Content-Type必须是application/json(大小写敏感,不能是application/json; charset=utf-8,虽然多数情况兼容,但某些中间件会 strict check) -
Body必须是io.Reader,用bytes.NewReader(jsonBytes),不能传字符串或strings.NewReader(虽能编译,但部分版本会 panic) - 结构体字段要加
json:tag,否则BodyParser不识别字段
资源清理容易被忽略:goroutine 和连接池不会自动关
app.Test() 不触发 app.Shutdown(),所以如果你在 handler 里起了 goroutine(比如发异步通知)、复用了全局 DB 连接池、或开了 time.Ticker,这些资源会在测试结束后继续存活——轻则内存泄漏,重则干扰后续测试。
建议做法:
- 在
TestXxx函数开头调用t.Cleanup(func(){ /* 关闭 DB / 取消 ticker / stop goroutine */ }) - 避免在 handler 中做长期后台任务;真需要,用
context.WithTimeout控制生命周期 - 测试中若用
sql.Open创建 DB,务必在Cleanup中调db.Close()
最易被忽略的是:没有 Cleanup 的测试,在本地反复运行几十次后,go tool pprof 会发现 goroutine 数持续上涨。











