用 httptest.newunstartedserver 测试 iris 路由最轻快可控:传 *iris.application 作 handler,必须调用 app.build(),手动注入路径参数与中间件,读响应 body 断言 json 数据,每个测试新建 app 实例防污染。

直接用 Iris 的 httptest 包跑路由测试,别碰真实 HTTP 服务或依赖外部数据库——这是最轻、最快、也最可控的方式。
用 httptest.NewUnstartedServer 启动未监听的测试服务器
Iris 本身不内置测试服务器,但 Go 标准库的 httptest 完全兼容。关键不是“启动服务”,而是把 *iris.Application 当作 http.Handler 传进去。
-
httptest.NewUnstartedServer不绑定端口,只包装 handler,避免端口占用和并发冲突 - 必须在测试前调用
app.Build(),否则中间件、路由注册可能未生效 - 不要用
app.Listen()或app.Run(),它们会阻塞并尝试监听,测试里完全不需要
func TestLoginRoute(t *testing.T) {
app := iris.New()
app.Post("/login", func(ctx iris.Context) {
ctx.JSON(iris.Map{"ok": true})
})
app.Build() // 必须调用!
server := httptest.NewUnstartedServer(app)
server.Start()
defer server.Close()
resp, _ := http.Post(server.URL+"/login", "application/json", strings.NewReader(`{"user":"a"}`))
if resp.StatusCode != 200 {
t.Fatal("expected 200")
}
}
路由参数与中间件必须显式注入测试上下文
Iris 的 Context 是运行时构造的,测试中无法直接 new。你得用 iris.New().Party + httptest.NewRequest 模拟完整链路,否则 ctx.Params().Get("id") 或 ctx.Values().Get("user_id") 全是空的。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
- 路径参数需在 request URL 中写死(如
/users/123),Iris 不会自动解析字符串路径 - 中间件若依赖
ctx.Next()或修改ctx.Values(),必须手动调用app.Use(...)注册,且顺序要和线上一致 - 如果用了
app.ConfigureContainer注入依赖,测试时得用app.PartyFunc或提前构造好 mock 实例传入 handler
JSON 请求体和响应断言要绕过 ctx.JSON 的封装
ctx.JSON 内部调用 json.Marshal 并设 header,但测试里你真正关心的是输出结构是否匹配,而不是它有没有设 Content-Type。直接读响应 body 更可靠。
- 别信
resp.Header.Get("Content-Type")—— Iris 默认设了,但测试重点是数据,不是 header - 用
io.ReadAll(resp.Body)拿原始字节,再json.Unmarshal到 struct 断言字段值 - 如果 handler 里用了
ctx.StopWithStatus或重定向,检查resp.StatusCode和resp.Header.Get("Location")即可,不用管 body
body, _ := io.ReadAll(resp.Body)
var data map[string]interface{}
json.Unmarshal(body, &data)
if data["ok"] != true {
t.Error("expected ok:true")
}
并发测试时注意 app 实例不能复用
每个测试函数必须新建 *iris.Application,因为 Iris 的路由树、中间件栈、配置都是实例级的。共用 app 会导致路由覆盖、中间件叠加、甚至 panic。
- 哪怕只是改了一个
app.ConfigureContainer的选项,也会污染其他测试 - 不要在
init()或包变量里存 app 实例;所有测试都走func TestXxx(t *testing.T)内部构造 - 如果多个测试共享相同路由逻辑,抽成函数(如
setupApp(t *testing.T) *iris.Application),但每次仍返回新实例
最易被忽略的一点:Iris 的 context.Context(小写)和标准库 context.Context(大写)命名冲突,测试里若混用 ctx 变量名,容易误传错类型导致静默失败——务必检查 handler 签名里的 iris.Context 是否被正确导入和使用。










