我正在为GoLang中的简单REST服务编写测试。但是,因为我使用julienschmidt/httprouter作为路由库。我正在努力学习如何写测试。
main.go
package main
func main() {
router := httprouter.New()
bookController := controllers.NewBookController()
router.GET("/book/:id", bookController.GetBook)
http.ListenAndServe(":8080", router)
}
控制器
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
如果我使用传统的处理程序,测试将很容易就像这样
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。所以我现在被卡住了
答案 0 :(得分:5)
为每个测试启动一个新路由器然后注册测试中的处理程序,然后将测试请求传递给路由器,而不是处理程序,以便路由器可以解析路径参数并将它们传递给处理程序。 / p>
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")
}
}
答案 1 :(得分:0)
您需要包装处理程序,以便可以http.HandlerFunc
:
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")
}
}
如果您的处理程序需要参数,您必须手动从请求中解析它们,或者只是将它们作为第三个参数提供。
答案 2 :(得分:0)
您可以在没有ServeHTTP
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))
}
答案 3 :(得分:-1)