#go #net-http #mux
#Вперед #net-http #mux
Вопрос:
Здесь я пытаюсь написать тест для REST-клиента, записывая apiOutput в http.ResponseWriter, но я всегда получаю {nil nil} в качестве apiResponse.
Может ли кто-нибудь помочь мне указать на ошибку?
func Test_Do(t *testing.T) {
mux := http.NewServeMux()
server := httptest.NewServer(mux)
t.Cleanup(server.Close)
config := NewClientConfig()
config.BaseURL = server.URL
client, err := NewClient(config)
if err != nil {
t.Fatal(err)
}
apiResponse := struct {
Id string `json:"id"`
Error error `json:"error"`
Data interface{} `json:"data"`
}{}
apiOutput := []byte(`{
"id":"1",
"error":nil,
"data":[{"IP": "1.2.2.3"}]}`)
mux.HandleFunc("/api/v1/hosts", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Write(apiOutput)
})
t.Run("Get Host Details", func(t *testing.T) {
req, err := client.MakeGetRequest(http.MethodGet, "/api/v1/hosts", nil)
if err != nil {
t.Fatal(err)
}
resp, err1 := client.Do(req, amp;apiResponse)
if err1 != nil {
t.Fatalf("failed with statusCode: %d, error: %s", resp.StatusCode, err1)
}
if apiResponse.Id != "1" || apiResponse.Error != nil {
t.Errorf("Client.Do() problem unmarshaling problem: got %#v", apiResponse)
}
fmt.Printf("%v", apiResponse)
})
}
func (c *Client) Do(req *http.Request, v interface{}) (*http.Response, error) {
resp, err := c.HTTPClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if errorResponse := c.CheckResponse(resp); errorResponse != nil {
return resp, errorResponse
}
if v != nil {
if w, ok := v.(io.Writer); ok {
io.Copy(w, resp.Body)
} else {
decErr := json.NewDecoder(resp.Body).Decode(v)
if decErr == io.EOF {
decErr = nil // ignore EOF errors caused by empty response body
}
if decErr != nil {
err = decErr
}
}
}
return resp, err
}
Вывод:
Test_Do/Get_Host_Details: clients_test.go:269: Client.Do() problem unmarshaling problem: got struct { Id string "json:"id""; Error error "json:"error""; Data interface {} "json:"data"" }{Id:"", Error:error(nil), Data:interface {}(nil)}
{ <nil> <nil>}
Комментарии:
1. @MuffinTop обновлен с Client.Do
2. Что, если вы измените
w.Write(apiOutput)
наfmt.Fprint(w, apiOutput)
? Именно так я пишу HTTP-ответы, и у меня это работает без сбоев. Также задайте код состояния для макетного ответа.w.WriteHeader(http.StatusOK)
3. Я получил ту же ошибку, что и я, я попробовал это. изменение на
fmt.Fprint(w, apiOutput)?
4. возможно, это может быть полезно посмотреть youtube.com/watch?v=hVFEV-ieeew
5. Обратите внимание, что
nil
это недопустимое значение json, поэтому вашеapiOutput
текущее значение сломано и приведет к сбою демаршализации / декодирования. Обратите также внимание, что вы не можете использоватьerror
тип интерфейса в качестве целевого объекта для разархивирования, если вы ожидаете, что в нем действительно что-то разархивируется (т. Е. Некоторое фактическое значение, отличное от null), это потому, что в качестве целевого объекта для разархивирования могут использоваться только пустые типы интерфейсов (если базовый динамический тип не выделен заранее).