Go语言如何Mock fiber.Ctx?测试触发空指针panic问题
解决Fiber中间件测试中空指针panic的问题
你遇到的错误是因为直接实例化fiber.Ctx{}导致的——Fiber的Ctx结构体内部包含大量未初始化的指针字段(比如底层HTTP请求/响应对象),调用c.GetReqHeaders()或c.SendStatus()时会访问这些空指针,触发分段错误。
错误信息
--- FAIL: TestCheckHeaders (0.00s)
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x12085f0]
解决方案
Fiber不允许手动实例化fiber.Ctx,正确的做法是通过Fiber应用实例的Test()方法模拟请求,自动生成已初始化的上下文对象。修改后的测试代码如下:
CheckHeaders_test.go
package middleware import ( "net/http" "net/http/httptest" "testing" "github.com/gofiber/fiber/v2" ) func TestCheckHeaders(t *testing.T) { tests := []struct { name string requestHeaderValue string expectedStatus int }{ { name: "headerValue为true,允许请求通过", requestHeaderValue: "true", expectedStatus: http.StatusOK, }, { name: "headerValue不为true,返回401", requestHeaderValue: "false", expectedStatus: http.StatusUnauthorized, }, { name: "缺少headerValue,返回401", requestHeaderValue: "", expectedStatus: http.StatusUnauthorized, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // 创建Fiber应用实例 app := fiber.New() // 注册待测试的中间件 app.Use(CheckHeaders) // 添加测试路由,用于验证中间件通过后的响应 app.Get("/test", func(c *fiber.Ctx) error { return c.SendStatus(http.StatusOK) }) // 构建测试请求 req := httptest.NewRequest(http.MethodGet, "/test", nil) if tt.requestHeaderValue != "" { req.Header.Set("headerValue", tt.requestHeaderValue) } // 执行测试请求 resp, err := app.Test(req) if err != nil { t.Fatalf("执行请求失败: %v", err) } defer resp.Body.Close() // 验证响应状态码是否符合预期 if resp.StatusCode != tt.expectedStatus { t.Errorf("预期状态码 %d,实际得到 %d", tt.expectedStatus, resp.StatusCode) } }) } }
核心说明
- 借助
fiber.New()创建真实的Fiber应用,让中间件在标准Fiber环境中运行,避免手动模拟Ctx的复杂依赖问题。 - 使用
httptest.NewRequest()灵活构造测试请求,可自由设置请求头参数。 app.Test()方法会自动创建并初始化fiber.Ctx对象,内部处理所有底层HTTP依赖,彻底避免空指针panic。- 测试用例覆盖了三种核心场景,全面验证中间件的逻辑正确性。
内容的提问来源于stack exchange,提问作者Taha Khan
相关产品推荐
相关产品推荐

