回答

收藏

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

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

我有以下代码:- ^! T% w* J8 U% a
    3 @0 e' r: a2 h0 @# ]0 T3 Z( U
  • 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/希望得到一些指导: j$ m9 ^0 K* I
  • 我想到了这个(无耻地从 go OAuth https://code.google.com/p/goauth2/source/browse/oauth/oauth_test.go复制测试):$ x- n& D, a* ?" ?# Z
  • [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]               6 l, R. y! M) T& q. W
  •     解决方案:                                                               
    ! }9 ~3 y/ b( Z2 z" c# G; C/ c
  •                                                                 httptest 做两种测试:响应和服务器, N, R; V' ^1 C4 [5 ^
  • 反应测试:[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)           }}
    ! R8 E3 m5 ~2 E* l3 A
服务器测试(这是你需要使用的):
3 B) g6 q5 S( Q2 N* s7 y  U/ _: N

    5 ~) ~4 r8 Q7 f$ j- ~" R6 D
  • 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)% m9 i  n. |' Z; D& n5 d& h6 ?
编辑:对于我的记录器测试,我可以这样使用我的 http 处理程序:
; U* ~' m$ S2 L; R
    handler(resp,req)1 b' j$ N/ C/ l$ L: p
但是我的原始代码没有默认使用 mux来自 Gorilla/mux),并且我对 mux 有一些包装,如插入服务器日志记录和添加请求(Gorilla/context),所以我必须去 mux 和调用 ServeHTTP
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则