2015-04-20 1 views
-2

Я пытаюсь проверить 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 по какой-то причине является нулевым. Есть идеи?

+0

не следует ли вам проверять ir.Err _after_ вы вызываете ir.Client.Do в Make()? Кроме того, перед «return nil» вы должны вызвать log.Print (ir.Err), чтобы получить сообщение об ошибке. – rob74

+0

Показать трассировку стека. – rightfold

+0

Спасибо, ребята. Я понял это. Посмотрите на мой ответ. Проверка ir.Err верна там, так как у меня есть другие методы, кроме Make on struct (например, готовьтесь к сборке HTTP-запроса). И в моем коде я хочу свести к минимуму повторяющиеся проверки ошибок, поэтому все методы просто пропускают их тело, если один из предыдущих методов структуры не удался. Затем я обрабатываю ошибку в конце. Все, что нужно было понять, это добавить в мой код несколько log.Print (ir.Err), и стало легко увидеть эту проблему. –

ответ

0

Ok. Я нашел проблему. Лучшая регистрация ошибок на самом деле показала, что моя ошибка была очень простой.

Я проходил это как URL, чтобы издевались HTTP-клиент:

host/api/v1/tokens/ 

Что было в результате этой ошибки:

Post host/api/v1/tokens/: unsupported protocol scheme 

Видимо URL должен включать в себя правильную схему HTTP (HTTP://), даже если вы используете тестовый сервер.

Смежные вопросы