测试基于gin的REST API,在使用net/http/httptest时无法获取参数。

huangapple go评论123阅读模式
英文:

Testing gin based REST API not getting params while using net/http/httptest

问题

我正在开发一个基于Gin Go的REST API,端点的代码如下所示:

  1. func carsByType(c *gin.Context) {
  2. fmt.Println("Go Request in Handler...")
  3. carType := c.Params.ByName("type")
  4. fmt.Println(carType)
  5. if carType != "" {
  6. }
  7. c.JSON(http.StatusBadRequest, gin.H{"result": "Bad request"})
  8. return
  9. }
  10. func main() {
  11. router := gin.Default()
  12. router.GET("/cars/:type", carsByType)
  13. router.Run(":80")
  14. }

当我通过浏览器和cURL请求端点时,一切正常,可以获取到carType的值。但是当我运行测试时,它返回了"bad request",并且carType的值是""。

用于测试端点的代码如下所示:

  1. func TestGetcarsByType(t *testing.T) {
  2. gin.SetMode(gin.TestMode)
  3. handler := carsByType
  4. router := gin.Default()
  5. router.GET("/cars/1", handler)
  6. req, err := http.NewRequest("GET", "/cars/1", nil)
  7. if err != nil {
  8. fmt.Println(err)
  9. }
  10. resp := httptest.NewRecorder()
  11. router.ServeHTTP(resp, req)
  12. assert.Equal(t, resp.Code, 200)
  13. }

我做错了什么?

英文:

I am developing a REST API based on Gin Go, the endpoint looks something like below:

  1. func carsByType(c *gin.Context) {
  2. fmt.Println("Go Request in Handler...")
  3. carType := c.Params.ByName("type")
  4. fmt.Println(carType)
  5. if carType != "" {
  6. }
  7. c.JSON(http.StatusBadRequest, gin.H{"result": "Bad request"})
  8. return
  9. }
  10. func main() {
  11. router := gin.Default()
  12. router.GET("/cars/:type", carsByType)
  13. router.Run(":80")
  14. }

When I am making request to the endpoint via browser and cURL its just working fine, getting the carType value but when I am running the tests its returning bad request and getting carType is "".

For testing the endpoint my test code looks like this:

  1. func TestGetcarsByType(t *testing.T) {
  2. gin.SetMode(gin.TestMode)
  3. handler := carsByType
  4. router := gin.Default()
  5. router.GET("/cars/1", handler)
  6. req, err := http.NewRequest("GET", "/cars/1", nil)
  7. if err != nil {
  8. fmt.Println(err)
  9. }
  10. resp := httptest.NewRecorder()
  11. router.ServeHTTP(resp, req)
  12. assert.Equal(t, resp.Code, 200)
  13. }

What am I doing wrong?

答案1

得分: 9

router.GET("/cars/1", handler) 应该改为 router.GET("/cars/:type", handler) 在你的测试中。

请注意,更好的做法(更易测试,减少路由的重复)是创建一个 SetupRouter() *gin.Engine 函数,该函数返回所有的路由。例如:

  1. // package main
  2. // server.go
  3. // 这是你创建 gin.Default() 并添加路由的地方
  4. func SetupRouter() *gin.Engine {
  5. router := gin.Default()
  6. router.GET("/cars/:type", carsByType)
  7. return router
  8. }
  9. func main() {
  10. router := SetupRouter()
  11. router.Run()
  12. }
  13. // router_test.go
  14. testRouter := SetupRouter()
  15. req, err := http.NewRequest("GET", "/cars/1", nil)
  16. if err != nil {
  17. fmt.Println(err)
  18. }
  19. resp := httptest.NewRecorder()
  20. testRouter.ServeHTTP(resp, req)
  21. assert.Equal(t, resp.Code, 200)
英文:

router.GET("/cars/1", handler) should be router.GET("/cars/:type", handler) in your test.

Note that a better (more testable; less duplication of routes) would be to create a SetupRouter() *gin.Engine function that returns all of your routes. e.g.

  1. // package main
  2. // server.go
  3. // This is where you create a gin.Default() and add routes to it
  4. func SetupRouter() *gin.Engine {
  5. router := gin.Default()
  6. router.GET("/cars/:type", carsByType)
  7. return router
  8. }
  9. func main() {
  10. router := SetupRouter()
  11. router.Run()
  12. }
  13. // router_test.go
  14. testRouter := SetupRouter()
  15. req, err := http.NewRequest("GET", "/cars/1", nil)
  16. if err != nil {
  17. fmt.Println(err)
  18. }
  19. resp := httptest.NewRecorder()
  20. testRouter.ServeHTTP(resp, req)
  21. assert.Equal(t, resp.Code, 200)

huangapple
  • 本文由 发表于 2016年3月14日 21:22:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/35988767.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定