【问题标题】:golang how to live test an http server?golang如何现场测试一个http服务器?
【发布时间】:2017-02-26 21:05:44
【问题描述】:

我使用 gotests 和 gorilla mux,我可以对我的 http handlefunc 处理程序进行单元测试,但它们不会像在 gorilla 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 请求,并且 没有考虑到我的主路由器。这对于单元测试功能很好, 但我认为最好只编写一个测试整体的集成测试 事情并一口气把所有东西都排除在外。

【问题讨论】:

    标签: go


    【解决方案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 mux,但此答案中的方法和详细信息适用于任何满足 http.Handler 接口的路由器。

    【讨论】:

    • 我在初始化服务器后在 echo labstack 上试过这个:= app.Run(), ts := httptest.NewServer(server) 也可以正常工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-15
    • 2011-11-08
    • 2014-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多