unit-testing - 需要帮助查明中间件测试中零引用错误的原因(Golang)
问题描述
在为我的 http 处理程序(特别是身份验证中间件)编写单元测试时,我遇到了“无效的内存地址或 nil 指针取消引用”错误。
这是要测试的功能:
func Authenticate(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
var err error
ck, err := req.Cookie("session")
if err != nil {
w.Header().Add("Authorization", "expired/invalid")
next.ServeHTTP(w, req)
return
}
r, err := env.Db.VerifySession(ck.Value)
if err != nil {
http.Error(w, http.StatusText(500), http.StatusInternalServerError)
return
}
if r == "expired/invalid" {
ck.MaxAge = -1
http.SetCookie(w, ck)
w.Header().Add("Authorization", r)
next.ServeHTTP(w, req)
return
}
w.Header().Add("Authorization", r)
next.ServeHTTP(w, req)
})
}
引发错误的特定测试用例:
rec = httptest.NewRecorder()
req, _ = http.NewRequest("GET", "/", nil)
c := &http.Cookie{
Name: "session",
Value: "success",
}
req.AddCookie(c)
routes.Authenticate(http.NotFoundHandler()).ServeHTTP(rec, req)
assert.Equal("admin", rec.Header().Get("Authorization"))
用于测试的 env.DB.VerifySession 的模拟版本:
func (mdb *mockdb) VerifySession(val string) (string, error) {
switch val {
case "success":
return "admin", nil
case "failure":
return "expired/invalid", nil
default:
return "", errors.New("500")
}
}
我已经为 Authenticate() 的第一部分编写了一个通过测试:如果没有找到“会话”cookie,则测试确认响应标头已适当更新。但是,当我传入一个“会话”cookie 时,就像上面的测试用例一样,Authenticate() 将运行到r, err := env.Db.VerifySession(ck.Value)
. 尝试在调试模式下跳过或进入该函数调用会导致抛出 nil 指针错误。
我不认为问题出在 env.Db 变量上,因为我已经使用相同的变量成功地在我的非中间件处理程序上运行了一套测试而没有问题。
我还可以通过调试确认“会话”cookie 确实存在。
任何关于这里发生的事情的指导将不胜感激。
解决方案
没关系,我意识到问题所在。对于我的其他路线,我将 env 变量作为参数传递。我需要找到一种方法来为中间件提供访问权限。
我想我会将中间件定义为 env 上的方法。
推荐阅读
- android - Android 构建在 Mac 机器中失败
- swift - 在主线程中调用方法会影响其子方法
- laravel - 只获取一列并使用 laravel 中的“with()”函数为该列创建一个别名
- python - 删除在Python中特定列表中具有值的文件后如何查找唯一文件?
- android - Android 支持不同的屏幕尺寸
- c# - 如何创建无限运行的任务循环?
- python - 在 Python 中标记一个句子并重新连接结果
- java - 使用 Open JDK 10.0.2 时,VirtualMachine attach 抛出 com.sun.tools.attach.AgentLoadException: 0
- c# - Sabre,获取 sessionRQ
- javascript - 如何获得父 div 中子元素的总和?