iris.test()是iris框架封装的快捷测试入口,本质基于net/http/httptest,需在测试函数中新建app实例、预先注册路由和中间件,通过传入httptest.responserecorder和http.request进行状态码、header、body等断言,并支持显式构造带路径参数、query、form或json的请求。

iris.Test() 函数怎么用
iris 框架自带 iris.Test(),它本质是封装了 net/http/httptest 的快捷测试入口,适合快速验证路由和处理器逻辑。别自己手写 httptest.NewServer 或手动构造 http.Request——那绕远了。
关键点:必须在测试函数里调用 app := iris.New() 创建新实例,不能复用全局 app;否则并发测试会互相污染状态。
-
iris.Test()第二个参数是测试函数,接收*httptest.ResponseRecorder和*http.Request,可直接断言响应状态码、Header、Body - 路由注册必须在
iris.Test()调用前完成,否则 404 - 若测试中间件,确保它已通过
app.Use()或app.UseRouter()注册,且顺序与运行时一致
如何 mock 数据库或外部依赖
iris 本身不处理依赖注入,所以测试时得主动替换。常见做法是把数据库操作封装成接口,测试时传入 fake 实现。
比如你有个 UserService 依赖 *sql.DB,不要在 handler 里直接 new DB,而是通过参数或字段注入:
func NewUserHandler(repo UserRepo) http.HandlerFunc {
return func(ctx iris.Context) {
users, _ := repo.FindAll()
ctx.JSON(users)
}
}
- 测试时传入自定义
fakeRepo,实现UserRepo接口,返回预设数据 - 避免在测试中启动真实数据库;哪怕用 sqlite 内存模式,也增加延迟和 flaky 风险
- 如果用了第三方 ORM(如 gorm),mock 其
*gorm.DB通常很重,不如直接 mock 上层 service 接口
测试带参数的路由(path/query/form)
iris 的路径参数(:id、*path)和 query 参数,在 iris.Test() 中需显式构造 URL 或设置 request body。
- 路径参数:URL 里直接写,例如
/users/123,handler 中用ctx.Params().Get("id")获取 - query 参数:拼在 URL 后,如
/search?q=golang&page=1,用ctx.URLParam("q")或ctx.FormValue("q") - form-data 或 JSON body:用
iris.WithRequestBody(...)选项,或手动设置req.Body并调用req.ParseForm()/json.NewDecoder(req.Body).Decode() - 注意:如果 handler 里混用
ctx.FormValue()和ctx.ReadJSON(),测试时要匹配 Content-Type,否则读不到数据
为什么 TestMain 不推荐用于 iris 初始化
有些用户想在 TestMain 里启动一次 iris server 复用到所有测试,这不可行——iris 的 iris.Test() 是无服务进程的纯内存测试,而 app.Listen() 启动的是真实 HTTP server,两者模型冲突。
-
TestMain里调app.Listen()会导致端口占用、goroutine 泄漏、无法并发执行 - iris 的测试设计哲学是“每个测试 case 独立初始化 + 独立销毁”,开销极小,没必要优化这点
- 真要测集成行为(比如反向代理、TLS、跨域),应该单独写 e2e 测试,用
httptest.NewUnstartedServer或真实部署环境
最常被忽略的是:handler 里调用 ctx.Next() 时,若中间件 panic 了,测试里不会自动捕获——得用 defer/recover 包一层,或者检查 recorder.Code 是否为 500 并结合日志断言。











