Я пытаюсь проверить HTTP-запрос в моей библиотеке Go. Объект, который делает вызов принимает объект HTTP клиента с помощью инъекции зависимостей так в моем тесте я насмешливый HTTP-клиент, как это:Перейти Nil Ошибка разыменования при тестировании HTTP-запроса
func TestMyObject(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
w.Header().Set("Content-Type", "application/json")
fmt.Fprintln(w, mockJSONResponse)
}))
defer server.Close()
// Make a transport that reroutes all traffic to the example server
transport := &http.Transport{
Proxy: func(req *http.Request) (*url.URL, error) {
return url.Parse(server.URL)
},
}
// Make a http.Client with the transport
httpClient := &http.Client{Transport: transport}
// I am passing the httpClient to my object
}
Вот как запрос HTTP сделан в пределах моего объекта:
// Make - makes a prepared HTTP request
func (ir *MyObject) Make() *http.Response {
if ir.Err != nil {
return nil
}
ir.resp, ir.Err = ir.Client.Do(ir.req)
runtime.SetFinalizer(ir, func(ir *MyObject) {
ir.resp.Body.Close()
})
ir.logReqRes()
ir.checkErrorResponse()
return ir.resp
}
Я получаю ноль ошибки указателя разыменования хотя:
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
в этой функции (я пытаюсь войти ответ):
// Logs request and response
func (ir *MyObject) logReqRes() {
log.Print("AAAAAAA")
log.Print(ir.resp)
log.Print("AAAAAAA")
if reqInfo, err := httputil.DumpRequest(ir.req, true); err == nil {
log.Print("Logging request:")
log.Print(string(reqInfo))
}
if respInfo, err := httputil.DumpResponse(ir.resp, true); err == nil {
log.Print("Logging response:")
log.Print(string(respInfo))
}
}
Как вы можете видеть, ir.resp по какой-то причине является нулевым. Есть идеи?
не следует ли вам проверять ir.Err _after_ вы вызываете ir.Client.Do в Make()? Кроме того, перед «return nil» вы должны вызвать log.Print (ir.Err), чтобы получить сообщение об ошибке. – rob74
Показать трассировку стека. – rightfold
Спасибо, ребята. Я понял это. Посмотрите на мой ответ. Проверка ir.Err верна там, так как у меня есть другие методы, кроме Make on struct (например, готовьтесь к сборке HTTP-запроса). И в моем коде я хочу свести к минимуму повторяющиеся проверки ошибок, поэтому все методы просто пропускают их тело, если один из предыдущих методов структуры не удался. Затем я обрабатываю ошибку в конце. Все, что нужно было понять, это добавить в мой код несколько log.Print (ir.Err), и стало легко увидеть эту проблему. –