我正在嘗試使用 httptest.NewServer 進行測驗,但遇到了障礙。
在我的代碼中,我正在向外部 API 發出 GET 請求,我想使用 httptest.NewServer 為此撰寫一個測驗。
這是我發出請求的代碼(main.go):
package main
import (
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
)
type HTTPClient interface {
Do(req *http.Request) (*http.Response, error)
}
type NewRequest interface {
NewRequest(method string, url string, body io.Reader) (*http.Request, error)
}
var (
Client HTTPClient
)
func init() {
Client = &http.Client{}
}
func main() {
url := "https://httpbin.org/get"
GetData(url)
}
func GetData(url string) (*http.Response, error) {
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
log.Fatalln(err)
return nil, err
}
resp, err := Client.Do(req)
if err != nil {
log.Fatalln(err)
return nil, err
}
defer resp.Body.Close()
responseBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
return nil, err
}
fmt.Println(resp.Status)
fmt.Println(string(responseBody))
return resp, nil
}
當我運行它時,它作業正常。
這是我的測驗檔案:
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
"net/http/httptest"
"testing"
)
func TestYourHTTPGet(t *testing.T){
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, `response from the mock server goes here`)
}))
defer ts.Close()
mockServerURL := ts.URL
resp, err := GetData(mockServerURL)
if err != nil {
fmt.Println("Error 1: ", err)
}
defer resp.Body.Close()
responseBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal("Error 2: ", err)
}
fmt.Println(resp.Status)
fmt.Println(string(responseBody))
}
當我運行時,go test我收到錯誤:http: read on closed response body. 如果我defer resp.Body.Close()從main.go測驗中洗掉正確通過。
我不確定為什么會發生這種情況,并希望有人能解釋這里發生了什么?
uj5u.com熱心網友回復:
你GetData()的回傳是一個指標。你跑GetData()進去main.go,當回車時,它會關閉resp.body. 如果你再讀一遍,它會導致http: read on closed response body
所以如果你想再次閱讀正文,你不應該回傳*http.Response,你應該克隆resp.body回傳
uj5u.com熱心網友回復:
正如@Cerise Limón 所說,您打了resp.Body.Close()兩次電話,然后嘗試閱讀封閉的正文。要修復您的代碼,您可以從GetData函式中洗掉主體處理并在外部執行GetData或回傳主體并且不要在測驗中讀取它。
main.go:
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
)
var Client = &http.Client{}
func main() {
url := "https://httpbin.org/get"
status, data, err := GetData(url)
if err != nil {
log.Fatalln(err)
}
fmt.Println(status)
fmt.Println(string(data))
}
func GetData(url string) (status string, body []byte, err error) {
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
return
}
resp, err := Client.Do(req)
if err != nil {
return
}
defer resp.Body.Close()
body, err = ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatalln(err)
}
return resp.Status, body, nil
}
main_test.go:
package main
import (
"fmt"
"net/http"
"net/http/httptest"
"testing"
)
func TestYourHTTPGet(t *testing.T){
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, `response from the mock server goes here`)
}))
defer ts.Close()
mockServerURL := ts.URL
status, data, err := GetData(mockServerURL)
if err != nil {
fmt.Println("Error 1: ", err)
}
fmt.Println(status)
fmt.Println(string(data))
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/365982.html
標籤:走
