回答

收藏

如何使用 httptest 在 Go 中测试 http 调用

技术问答 技术问答 228 人阅读 | 0 人回复 | 2023-09-12

我有以下代码:
7 }/ D6 D: a0 b0 G
    - x5 l$ `! ^  l# I2 _  d; \
  • package mainimport  "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=#UCL"  pauseDuration = 5 * time.Second)func retrieveTweets(c chan我想为它编写一些测试,但我不确定如何使用 httptest 包http://golang.org/pkg/net/http/httptest/希望得到一些指导" X* k. g) D9 A1 g# _" u8 y
  • 我想到了这个(无耻地从 go OAuth https://code.google.com/p/goauth2/source/browse/oauth/oauth_test.go复制测试):
    " x3 `$ n- U- _( ^$ l7 M% g: d6 a4 L
  • [code]var request = struct    path,query       string // request    contenttype,body string // response}{    path:        "/search.json?",   query:       "q=#Kenya",   contenttype: "application/json",   body:        twitterResponse,}var  twitterResponse = `{ 'resultstext':'hello','id_str':'34455w4','from_user_name':'bob','from_user_id_str」`)func TestRetrieveTweets(t *testing.T)    handler := func(w http.ResponseWriter,r *http.Request)              w.Header().Set("Content-Type",request.contenttype)        io.WriteString(w,request.body)   }    server := httptest.NewServer(http.HandlerFunc(handler))    defer server.Close()    resp,err := http.Get(server.URL)    if err != nil              t.Fatalf("Get: %v",err)   }    checkBody(t,resp,twitterResponse)}func checkBody(t *testing.T,r *http.Response,body string)    b,err := ioutil.ReadAll(r.Body)    if err != nil              t.Error("reading reponse body: %v,want %q",err,body)   }    if g,w := string(b),body; g != w              t.Errorf("request body mismatch: got %q,want %q",g,w)  code]               
    ' P2 X# Y  O" d6 O2 O" j6 H
  •     解决方案:                                                               0 R5 b3 [* C9 q4 I
  •                                                                 httptest 做两种测试:响应和服务器
    " g: F5 p$ l) O. v$ Y# a
  • 反应测试:[code]func TestHeader3D(t *testing.T)    resp := httptest.NewRecorder()    uri := "/3D/header/?"    path := "/home/test"    unlno := "997225821"    param := make(url.Values)    param["param1"] = []string{path}    param["param2"] = []string{unlno}    req,err := http.NewRequest("GET",uri param.Encode(),nil)    if err != nil            t.Fatal(err)   }    http.DefaultServeMux.ServeHTTP(resp,req)    if p,err := ioutil.ReadAll(resp.Body); err != nil                t.Fail()    } else                if strings.Contains(string(p),"Error")                        t.Errorf("header response shouldn't return error: %s",p)        else if !strings.Contains(string(p),`expected result`)                        t.Errorf("header response doen't match:\n%s",p)           }}
    : [2 J- ]- [7 a, y
服务器测试(这是你需要使用的):
* ~$ ?+ [, N' A
    ) q% P" o) G+ X. F9 V- i
  • func TestIt(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()    twitterUrl = ts.URL    c := make(chan *twitterResult)    go retrieveTweets(c)    tweet := 顺便说一句,你不需要介绍 r 指针,因为它已经是指针了。[code]err = json.Unmarshal(body,r)
    * q) |1 ~) P1 p4 i- h1 G" E5 z) w
编辑:对于我的记录器测试,我可以这样使用我的 http 处理程序:) o" Y& H6 @: y7 m" E$ n! V
    handler(resp,req)$ @1 W% G; Q* S' G: E$ k
但是我的原始代码没有默认使用 mux来自 Gorilla/mux),并且我对 mux 有一些包装,如插入服务器日志记录和添加请求(Gorilla/context),所以我必须去 mux 和调用 ServeHTTP
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则