V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
maocat
V2EX  ›  程序员

用反射闭包了一下 Gin 的 HandlerFunc, 我终于可以开开心心的写单元测试了

  •  
  •   maocat · 2023-03-16 15:38:11 +08:00 · 1000 次点击
    这是一个创建于 651 天前的主题,其中的信息可能已经有所发展或是发生改变。

    上家公司是用 go-micro 写 rpc, 现在跑过来写 gin, 写单元测试构造用例可太麻烦了

    用反射封装了一下,我又回到当初写微服务的快乐了

    没有破坏路由也没有破坏中间件,就加了 req 和 resp 的反射封装

    废话多说,上个例子

    
    package main
    
    import (
    	"fmt"
    	"github.com/gin-gonic/gin"
    	"github.com/maocatooo/thin/gin_handler"
    )
    
    type Req struct {
    	Name string `json:"name"`
    }
    
    type Query struct {
    	Name string `form:"name"`
    }
    
    type Resp struct {
    	Code    int    `json:"code"`
    	Message string `json:"message"`
    }
    
    /*
    GET http://127.0.0.1:8080/ping?name=123
    */
    func Ping(ctx *gin.Context, req *Query, rsp *Resp) error {
    	fmt.Printf("Ping req: %+v \n", *req)
    	if req.Name == "123" {
    		return fmt.Errorf("err 123")
    	}
    	rsp.Code = 200
    	rsp.Message = req.Name
    	return nil
    }
    
    type A struct {
    	a string
    }
    
    /*
    POST http://127.0.0.1:8080/pong
    {
    	"name":"456"
    }
    */
    func (a A) Pong(ctx *gin.Context, req *Req, rsp *Resp) error {
    	fmt.Printf("Pong req: %+v \n", *req)
    	if req.Name == "123" {
    		return fmt.Errorf("123")
    	}
    	rsp.Code = 200
    	rsp.Message = req.Name
    	return nil
    }
    
    func main() {
    	r := gin.Default()
    	r.GET("/ping", gin_handler.Query(Ping))
    	r.POST("/pong", gin_handler.JSON(A{a: "a123"}.Pong))
    	_ = r.Run()
    }
    

    基佬链接: https://github.com/maocatooo/thin/tree/main/gin_handler

    求个 star

    1 条回复    2023-03-16 15:59:35 +08:00
    ternice
        1
    ternice  
       2023-03-16 15:59:35 +08:00
    gin 的单测很难写吗?

    ```
    //初始化路由和 handlers 可以全局初始化,
    r := gin.Default()
    // ..todo init handlers

    // 模拟发送
    reqBody := ``
    req, _ := http.NewRequest("GET", "/api/ping", strings.NewReader(reqBody))
    req.Header.Set("Content-Type", "application/json; charset=utf-8")

    recorder := httptest.NewRecorder()

    r.ServeHTTP(recorder, req)

    //处理结果
    rp := resp.Resp{}

    err := json.Unmarshal(recorder.Body.Bytes(), &rp)

    println(recorder.Body.String())

    if err != nil {
    t.Errorf(err.Error())
    }

    ```
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2983 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 14:37 · PVG 22:37 · LAX 06:37 · JFK 09:37
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.