gin-gonic / gin

Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API with much better performance -- up to 40 times faster. If you need smashing performance, get yourself some Gin.
https://gin-gonic.com/
MIT License
78.81k stars 8.02k forks source link

How to write request test ? #55

Closed kzjeef closed 10 years ago

kzjeef commented 10 years ago

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)
    }
}
javierprovecho commented 10 years ago

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

kzjeef commented 10 years ago

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.

shackra commented 7 years ago

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

ernsheong commented 7 years ago

@shackra see https://github.com/gin-gonic/gin/pull/37/files

EveryDayNew commented 5 years ago

@ernsheong you saved me

EveryDayNew commented 5 years ago

@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{} } `