Я столкнулся с ошибкой «неверный адрес памяти или разыменование нулевого указателя» при написании модульных тестов для моих обработчиков http - в частности, промежуточного программного обеспечения для аутентификации.
Вот проверяемая функция:
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 действительно существует.
Будем весьма благодарны за любые указания относительно того, что здесь происходит.