• gin单元测试启动服务后测试controller接口


    1、使用的包是 net/http/httptest 

    2、单元测试需要启动 gin 服务,然后 httptest.NewRequest 发送请求

    示例代码:

    mkdir gin
    cd gin
    go mod init example.com
    go get github.com/gin-gonic/gin
    go get github.com/stretchr/testify

    创建 web 控制器

    cd gin
    mkdir controller
    touch user.go
    touch user_test.go

    其中 user.go 的内容

    package controller
    
    import (
        "fmt"
        "net/http"
    
        "github.com/gin-gonic/gin"
    )
    
    // Param 请求参数
    type Param struct {
        Name string `json:"name"`
    }
    
    // helloHandler /hello请求处理函数
    func helloHandler(c *gin.Context) {
        var p Param
        if err := c.ShouldBindJSON(&p); err != nil {
            c.JSON(http.StatusOK, gin.H{
                "msg": "we need a name",
            })
            return
        }
        c.JSON(http.StatusOK, gin.H{
            "msg": fmt.Sprintf("hello %s", p.Name),
        })
    }
    
    // SetupRouter 路由
    func SetupRouter() *gin.Engine {
        router := gin.Default()
        router.POST("/hello", helloHandler)
        return router
    }

    单元测试代码 user_test.go

    package controller
    
    import (
        "encoding/json"
        "net/http"
        "net/http/httptest"
        "strings"
        "testing"
    
        "github.com/stretchr/testify/assert"
    )
    
    type p struct {
        name   string
        param  string
        expect string
    }
    
    // go test -timeout 30s -run ^Test_helloHandler$ example.com/controller
    func Test_helloHandler(t *testing.T) {
        // 定义两个测试用例
        tests := []p{
            {"base case", `{"name": "jack"}`, "hello jack"},
            {"bad case", "", "we need a name"},
        }
        r := SetupRouter()
        for _, tt := range tests {
            t.Run(tt.name, func(t *testing.T) {
                // mock一个HTTP请求
                req := httptest.NewRequest("POST", "/hello", strings.NewReader(tt.param))
                // mock一个响应记录器
                w := httptest.NewRecorder()
                // 让server端处理mock请求并记录返回的响应内容
                r.ServeHTTP(w, req)
                // 校验状态码是否符合预期
                assert.Equal(t, http.StatusOK, w.Code)
                // 解析并检验响应内容是否复合预期
                var resp map[string]string
                err := json.Unmarshal(w.Body.Bytes(), &resp)
                assert.Nil(t, err)
                assert.Equal(t, tt.expect, resp["msg"])
            })
        }
    }

    在controller所在的目录执行用例 (用 goland 和 vscode 都可以 , 用goland 可以很方便地看单元测试代码覆盖率)

    cd controller
    go test -timeout 30s -run ^Test_helloHandler$ example.com/controller

    需要启动 gin 服务器相对比较麻烦

  • 相关阅读:
    spring boot @value 使用
    mac Navicat premium 链接oracle
    List sort 排序
    mac 配置jdk+maven环境变量
    mybatis 根据主键批量insert或update
    git 常用命令
    SpringBoot整合Activiti案例
    Activiti网关-并行网关
    Activiti网关-包含网关
    Activiti网关-排他网关
  • 原文地址:https://www.cnblogs.com/xuweiqiang/p/16384643.html
Copyright © 2020-2023  润新知