Gin: How to write request test ?

Created on 8 Jul 2014  路  6Comments  路  Source: gin-gonic/gin

Use std and http handler can write following test case, but how to do similar thing in gin ?

I think the main point should be how to create a request and response and fill it into gin's Context structure...

package main

  import (
    "net/http"
    "net/http/httptest"
    "testing"
  )

func IndexHandler(res http.ResponseWriter, req *http.Request) {
    data, _ := json.Marshal("{'hello':'wercker!'}")
    res.Header().Set("Content-Type", "application/json; charset=utf-8")
    res.Write(data)
}

func TestHandleIndexReturnsWithStatusOK(t *testing.T) {
    request, _ := http.NewRequest("GET", "/", nil)
    response := httptest.NewRecorder()

    IndexHandler(response, request)

    if response.Code != http.StatusOK {
        t.Fatalf("Non-expected status code%v:\n\tbody: %v", "200", response.Code)
    }
}
question

Most helpful comment

Thanks for point out the #37.
I endup for this solution for testing without rewrite the router related code:.

in main.go

func GetMainEngine() *gin.Engine {
    r := gin.Default()

    v1 := r.Group("/v1")
    {
        v1.POST("/login", model.Login)
        v1.POST("/logou", model.Logout)
        v1.POST("/signup", model.Signup)
    }
    return r
}

func main() {
    GetMainEngine().Run(":8080")
}

in the main_test.go

func TestUserRegAndLogin(t *testing.T) {

    setupDB()
    defer clearDB()

    ts := httptest.NewServer(GetMainEngine())
... Other will be same.

And Close the issue.

All 6 comments

Please check some of the unit tests at https://github.com/gin-gonic/gin/pull/37. Is this what you were looking for?

Thanks for point out the #37.
I endup for this solution for testing without rewrite the router related code:.

in main.go

func GetMainEngine() *gin.Engine {
    r := gin.Default()

    v1 := r.Group("/v1")
    {
        v1.POST("/login", model.Login)
        v1.POST("/logou", model.Logout)
        v1.POST("/signup", model.Signup)
    }
    return r
}

func main() {
    GetMainEngine().Run(":8080")
}

in the main_test.go

func TestUserRegAndLogin(t *testing.T) {

    setupDB()
    defer clearDB()

    ts := httptest.NewServer(GetMainEngine())
... Other will be same.

And Close the issue.

@kzjeef can you expand the "... Other will be same." part to have a complete answer?

@ernsheong you saved me

@ernsheong I,m new and first use issues.How to write test? I want to test 'Get'.This is a traditional MVC.I just copied controller.
`package main

import (
"fmt"
"devops/xflow-be/conf"
"devops/xflow-be/router"
"xngo/lib/xlog"
)

func main() {

xlog.Logger.Info("app start")

r := router.NewRouter()

addr := fmt.Sprintf(":%d", conf.Config.App.Port)
r.Run(addr)

}`

`package router

import (
"github.com/gin-gonic/gin"
"devops/xflow-be/controller"
"devops/xflow-be/middleware"
)

func NewRouter() *gin.Engine {
app := gin.New()
skelCtl := controller.NewSkelController()
skelGroup := app.Group("/skel")
{
skelGroup.POST("/get", skelCtl.Get)
}
return app
`

`package controller

import (
"github.com/gin-gonic/gin"
"devops/xflow-be/include/entity"
"devops/xflow-be/include/req"
"devops/xflow-be/service"
)

type BaseController struct {

}

type SkelController struct {
BaseController
}

func NewSkelController() *SkelController {
return &SkelController{}
}

func (ts *SkelController)newService() *service.SkelService {
return service.NewSkelService()
}

func (ts *SkelController) Get(ctx *gin.Context) {
reqData := &req.ByIdReq{}
if err := ctx.BindJSON(reqData); err != nil {
ts.ReplyFail(ctx, err)
return
}

if ent, err := ts.newService().Get(reqData.Id); err != nil {
    ts.ReplyFail(ctx, err)
} else {
    ts.ReplyOk(ctx, ent)
}

}

func (ts *BaseController) ReplyOk(ctx *gin.Context, data interface{}) {
xlog.Logger.Info("replay ok", zap.Any("data", data))
if data == nil || data == "" {
ctx.JSON(http.StatusOK, gin.H{
"ret": 1,
})
} else {
ctx.JSON(http.StatusOK, gin.H{
"ret": 1,
"data": data,
})
}
}

func (ts *BaseController) ReplyFail(ctx *gin.Context, err interface{}) {
xlog.Logger.Error("replay fail", zap.Any("err", err))
ctx.JSON(http.StatusOK, gin.H{
"ret": 1000,
"msg": err,
})
}
package req

type ByIdReq struct {
Id interface{}
}

type ByFieldReq struct {
Name string
Value interface{}
}
`

Was this page helpful?
0 / 5 - 0 ratings

Related issues

xpbliss picture xpbliss  路  3Comments

sofish picture sofish  路  3Comments

gplume picture gplume  路  3Comments

oryband picture oryband  路  3Comments

nxvl picture nxvl  路  3Comments