首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用httprouter编写测试

如何用httprouter编写测试
EN

Stack Overflow用户
提问于 2017-04-19 17:31:32
回答 4查看 4.8K关注 0票数 10

我正在GoLang中为一个简单的REST服务编写测试。但是,因为我使用朱利安施密特/赫特普劳特作为路由库。我在为如何写测试而挣扎。

main.go

代码语言:javascript
复制
package main

func main() {
   router := httprouter.New()
   bookController := controllers.NewBookController()
   router.GET("/book/:id", bookController.GetBook)
   http.ListenAndServe(":8080", router)
}

控制器

代码语言:javascript
复制
package controllers

type BookController struct {}

func NewBookController *BookController {
   return &BookController()
}

func (bc BookController) GetBook(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
   fmt.Fprintf(w,"%s", p)
}

我的问题是:在GetBook既不是HttpHandler也不是HttpHandle的情况下,如何测试它?

如果我使用传统的处理程序,那么测试就会像这样简单

代码语言:javascript
复制
func TestGetBook(t *testing.T) {
  req, _ := http.NewRequest("GET", "/book/sampleid", nil)
  rr := httptest.NewRecorder()
  handler := controllers.NewBookController().GetBook
  handler.ServeHTTP(rr,req)
  if status := rr.code; status != http.StatusOK {
    t.Errorf("Wrong status")
  }
}

问题是,httprouter不是处理程序,也不是handlefunc。所以我现在被困住了

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-04-19 17:55:32

只需为每个测试旋转一个新路由器,然后注册被测试的处理程序,然后将测试请求传递给路由器,而不是处理程序,这样路由器就可以解析路径参数并将它们传递给处理程序。

代码语言:javascript
复制
func TestGetBook(t *testing.T) {
    handler := controllers.NewBookController()
    router := httprouter.New()
    router.GET("/book/:id", handler.GetBook)

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

    router.ServeHTTP(rr, req)
    if status := rr.Code; status != http.StatusOK {
        t.Errorf("Wrong status")
    }
}
票数 16
EN

Stack Overflow用户

发布于 2017-04-19 18:12:38

您需要包装处理程序,以便可以以http.HandlerFunc的形式访问它。

代码语言:javascript
复制
func TestGetBook(t *testing.T) {
    req, _ := http.NewRequest("GET", "/book/sampleid", nil)
    rr := httptest.NewRecorder()
    handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        controllers.NewBookController().GetBook(w, r, httprouter.Params{})
    })
    handler.ServeHTTP(rr,req)
    if status := rr.code; status != http.StatusOK {
        t.Errorf("Wrong status")
    }
}

如果处理程序需要参数,则必须手动解析请求中的参数,或者将它们作为第三个参数提供。

票数 3
EN

Stack Overflow用户

发布于 2018-12-04 07:44:57

不需要ServeHTTP,你可以试试这个。

代码语言:javascript
复制
func TestGetBook(t *testing.T) {
    req := httptest.NewRequest("GET", "http://example.com/foo", nil)
    w := httptest.NewRecorder()

    controllers.NewBookController().GetBook(w, req, []httprouter.Param{{Key: "id", Value: "101"}})

    resp := w.Result()
    body, _ := ioutil.ReadAll(resp.Body)

    t.Log(resp.StatusCode)
    t.Log(resp.Header.Get("Content-Type"))
    t.Log(string(body))
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43502432

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档