You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Go的httptest请求中传递Chi框架的路径参数?

解决Go中chi路由路径参数的单元测试传递问题

你之前用req.URL.Query().Set("uuid", "valid_uuid")无效的原因是:这个方法设置的是URL查询参数(即?uuid=xxx格式的参数),但你的业务代码通过chi.URLParam获取的是路径参数(URL路径中{uuid}占位符对应的部分),两者不是同一类型的参数,自然取不到。

下面提供两种可行的测试方案:

方案一:手动注入路径参数到请求上下文

chi路由会把路径参数存储在请求的上下文里,测试时可以直接构造路由上下文并注入到请求中:

import (
    "context"
    "net/http"
    "net/http/httptest"
    "github.com/go-chi/chi/v5"
)

func TestGetProduct(t *testing.T) {
    // 构造带路径的请求(路径里的uuid仅作占位,实际生效的是下面注入的参数)
    req := httptest.NewRequest("GET", "/products/any-uuid", nil)
    
    // 创建chi路由上下文并添加有效UUID参数
    routeCtx := chi.NewRouteContext()
    routeCtx.URLParams.Add("uuid", "123e4567-e89b-12d3-a456-426614174000")
    
    // 将路由上下文注入到请求的上下文
    req = req.WithContext(context.WithValue(req.Context(), chi.RouteCtxKey, routeCtx))
    
    // 调用handler并记录响应
    w := httptest.NewRecorder()
    GetProduct(w, req)
    
    // 添加断言逻辑,比如检查响应状态码
    if w.Code != http.StatusOK {
        t.Errorf("expected status %d, got %d", http.StatusOK, w.Code)
    }
}

方案二:启动测试服务器模拟完整路由匹配

如果想更贴近真实请求场景,可以注册完整的chi路由,通过测试服务器发送带路径参数的请求:

import (
    "net/http"
    "net/http/httptest"
    "github.com/go-chi/chi/v5"
)

func TestGetProductWithServer(t *testing.T) {
    // 注册路由
    router := chi.NewRouter()
    router.Get("/products/{uuid}", GetProduct)
    
    // 创建测试服务器
    testServer := httptest.NewServer(router)
    defer testServer.Close()
    
    // 发送带有效UUID路径参数的请求
    resp, err := http.Get(testServer.URL + "/products/123e4567-e89b-12d3-a456-426614174000")
    if err != nil {
        t.Fatalf("failed to send request: %v", err)
    }
    defer resp.Body.Close()
    
    // 断言响应状态码等
    if resp.StatusCode != http.StatusOK {
        t.Errorf("expected status %d, got %d", http.StatusOK, resp.StatusCode)
    }
}

内容的提问来源于stack exchange,提问作者Anshul Sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 05:16:35