php小編子墨為大家帶來了一篇關於Golang中使用httptest攔截和模擬HTTP回應的文章。在這篇文章中,我們將深入探討如何使用httptest套件進行HTTP請求的攔截和模擬回應,以便於進行單元測試和功能測試。透過使用httptest,我們可以輕鬆地模擬各種場景下的HTTP響應,進而測試我們的程式碼的正確性和穩健性。無論是對於初學者還是有經驗的開發者來說,掌握這些技巧都是非常有用的。接下來,讓我們一起來了解具體的實作方法吧!
我研究了可用於 golang 中模擬測試的各種不同工具,但我正在嘗試使用 httptest 來完成此任務。特別是,我有一個這樣的函數:
type contact struct { username string number int } func getResponse(c contact) string { url := fmt.Sprintf("https://mywebsite/%s", c.username) req, err := http.NewRequest(http.MethodGet, url, nil) // error checking resp, err := http.DefaultClient.Do(req) // error checking return response }
我讀過的很多文件似乎都需要建立客戶端介面或自訂傳輸。有沒有辦法在不更改此主程式碼的情況下模擬測試檔案中的回應?我想將我的客戶端、回應和所有相關詳細資訊保留在 getresponse
函數中。我可能有錯誤的想法,但我正在嘗試找到一種方法來攔截 http.defaultclient.do(req)
呼叫並返回自訂回應,這可能嗎?
我讀過似乎需要建立一個客戶端介面
根本不改變這個主要程式碼
保持程式碼乾淨是一個很好的做法,您最終會習慣它,可測試的程式碼更乾淨,更乾淨的程式碼更可測試,所以不必擔心更改您的程式碼(使用介面),這樣它就可以接受模擬對象。
最簡單形式的程式碼可以是這樣的:
package main import ( "fmt" "net/http" ) type contact struct { username string number int } type client interface { do(req *http.request) (*http.response, error) } func main() { getresponse(http.defaultclient, contact{}) } func getresponse(client client, c contact) string { url := fmt.sprintf("https://mywebsite/%s", c.username) req, _ := http.newrequest(http.methodget, url, nil) // error checking resp, _ := http.defaultclient.do(req) // error checking and response processing return response }
package main import ( "net/http" "testing" ) type mockclient struct { } // do function will cause mockclient to implement the client interface func (tc mockclient) do(req *http.request) (*http.response, error) { return &http.response{}, nil } func testgetresponse(t *testing.t) { client := new(mockclient) getresponse(client, contact{}) }
package main import ( "fmt" "io" "net/http" "net/http/httptest" ) type contact struct { username string number int } func main() { fmt.Println(getResponse(contact{})) } func getResponse(c contact) string { // Make a test server ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "your response") })) defer ts.Close() // You should still set your base url base_url := ts.URL url := fmt.Sprintf("%s/%s", base_url, c.username) req, _ := http.NewRequest(http.MethodGet, url, nil) // Use ts.Client() instead of http.DefaultClient in your tests. resp, _ := ts.Client().Do(req) // Processing the response response, _ := io.ReadAll(resp.Body) resp.Body.Close() return string(response) }
以上是Golang:使用 httptest 攔截和模擬 HTTP 回應的詳細內容。更多資訊請關注PHP中文網其他相關文章!