首頁 >後端開發 >Golang >如何使用 `httptest` 套件在 Go 中對 HTTP 呼叫進行單元測試?

如何使用 `httptest` 套件在 Go 中對 HTTP 呼叫進行單元測試?

Susan Sarandon
Susan Sarandon原創
2024-12-13 16:21:10567瀏覽

How to Unit Test HTTP Calls in Go using the `httptest` Package?

如何使用httptest 在Go 中測試HTTP 呼叫

單元測試是軟體開發的一個重要方面,對於Go 程式來說,httptest 套件提供了一個用於測試HTTP 呼叫的有用工具。本文將示範如何使用 httptest 為發出 HTTP 請求的 Go 程式碼撰寫單元測試。

挑戰

考慮以下Go 程式碼:

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "time"
)

type twitterResult struct {
    Results []struct {
        Text     string `json:"text"`
        Ids      string `json:"id_str"`
        Name     string `json:"from_user_name"`
        Username string `json:"from_user"`
        UserId   string `json:"from_user_id_str"`
    }
}

var (
  twitterUrl = "http://search.twitter.com/search.json?q=%23UCL"
  pauseDuration = 5 * time.Second
)

func retrieveTweets(c chan<- *twitterResult) {
    for {
        resp, err := http.Get(twitterUrl)
        if err != nil {
            log.Fatal(err)
        }

        defer resp.Body.Close()
        body, err := ioutil.ReadAll(resp.Body)
        r := new(twitterResult) //or &amp;twitterResult{} which returns *twitterResult
        err = json.Unmarshal(body, &amp;r)
        if err != nil {
            log.Fatal(err)
        }
        c <- r
        time.Sleep(pauseDuration)
    }

}

func displayTweets(c chan *twitterResult) {
    tweets := <-c
    for _, v := range tweets.Results {
        fmt.Printf("%v:%v\n", v.Username, v.Text)
    }

}

func main() {
    c := make(chan *twitterResult)
    go retrieveTweets(c)
    for {
        displayTweets(c)
    }

}
目標是為此程式碼編寫單元測試,重點是測試從Twitter 搜尋中檢索推文發出的HTTP 請求API.

使用httptest的解決方案

httptest 套件提供兩種類型的測試:回應測試和伺服器測試。對於這種場景,伺服器測試更合適。操作步驟如下:

  1. 建立測試伺服器:
func TestRetrieveTweets(t *testing.T){
    ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "application/json")
        fmt.Fprintln(w, `{"fake twitter json string"}`)
    }))
    defer ts.Close()
此程式碼建立測試伺服器,伺服器使用預先定義的JSON 回應。

  1. 更新原始內容程式碼:
twitterUrl = ts.URL
在原始程式碼中,twitterUrl 變數被修改為指向測試伺服器的URL,而不是實際的Twitter API 端點。

  1. 建立一個Channel:
c := make(chan *twitterResult)
原始程式碼中,channel 用來測試 goroutine 和 main goroutine 之間進行通訊。

  1. 啟動一個要檢索的 Goroutine推文:
go retrieveTweets(c)
此 goroutine 啟動從測試伺服器擷取推文的過程。

  1. 接收推文:
tweet := <-c
if tweet != expected1 {
    t.Fail()
}

tweet = <-c
if tweet != expected2 {
    t.Fail()
}
測試 goroutine 接收來自頻道的推文並檢查它們是否與預期結果匹配。

進一步注意事項

值得注意的是,測試並未驗證 HTTP 回應的內容。為了進行更徹底的測試,有必要將實際響應與預期響應進行比較。此外,測試伺服器應該返回更真實的回應結構,以準確模擬實際的 Twitter API。

以上是如何使用 `httptest` 套件在 Go 中對 HTTP 呼叫進行單元測試?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn