一尘不染

golang如何现场测试http服务器?

go

我使用了getests和gorilla mux,并且可以对我的http
handlefunc处理程序进行单元测试,但是它们没有像在大猩猩mux下那样响应正确的http请求方法。如何进行“实时服务器”版本的测试?

func main() {
    router := mux.NewRouter()
    router.HandleFunc("/", views.Index).Methods("GET")
}

func Index(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json; charset=UTF-8")
    w.WriteHeader(http.StatusOK)

    fmt.Fprintf(w, "INDEX\n")
}

func TestIndex(t *testing.T) {

    req, _ := http.NewRequest("GET", "/", nil)
    req1, _ := http.NewRequest("POST", "/", nil)
    rr := httptest.NewRecorder()

    handler := http.HandlerFunc(Index)

    type args struct {
        w http.ResponseWriter
        r *http.Request
    }
    tests := []struct {
        name string
        args args
    }{
        {name: "1: testing get", args: args{w: rr, r: req}},
        {name: "2: testing post", args: args{w: rr, r: req1}},
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            handler.ServeHTTP(tt.args.w, tt.args.r)
            log.Println(tt.args.w)
        })
    }
}

这里的问题是该函数同时响应get和post请求,而没有考虑我的主路由器。这对于单元测试功能是很好的,但是我认为最好编写一个集成测试来测试整个事情并一次性解决所有问题。


阅读 207

收藏
2020-07-02

共1个答案

一尘不染

使用net / http /
httptest.Server
类型来测试实时服务器。

func TestIndex(t *testing.T) {
  // Create server using the a router initialized elsewhere. The router
  // can be a Gorilla mux as in the question, a net/http ServeMux, 
  // http.DefaultServeMux or any value that statisfies the net/http
  // Handler interface.
  ts := httptest.NewServer(router)  
  defer ts.Close()

  newreq := func(method, url string, body io.Reader) *http.Request {
    r, err := http.NewRequest(method, url, body)
    if err != nil {
        t.Fatal(err)
    }
    return r
  }

  tests := []struct {
    name string
    r    *http.Request
  }{
    {name: "1: testing get", r: newreq("GET", ts.URL+"/", nil)},
    {name: "2: testing post", r: newreq("POST", ts.URL+"/", nil)}, // reader argument required for POST
  }
  for _, tt := range tests {
    t.Run(tt.name, func(t *testing.T) {
        resp, err := http.DefaultClient.Do(tt.r)
        defer resp.Body.Close()
        if err != nil {
            t.Fatal(err)
        }
        // check for expected response here.
    })
  }
}

尽管该问题使用Gorilla多路复用器,但此答案中的方法和详细信息适用于满足http.Handler接口的任何路由器。

2020-07-02