首頁 > 後端開發 > Golang > Golang:使用 httptest 攔截和模擬 HTTP 回應

Golang:使用 httptest 攔截和模擬 HTTP 回應

王林
發布: 2024-02-09 08:24:33
轉載
1180 人瀏覽過

Golang:使用 httptest 拦截和模拟 HTTP 响应

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{})
}
登入後複製

但是如果您更喜歡使用 httptest:

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中文網其他相關文章!

來源:stackoverflow.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板