The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
guonaihong

go test 常见套路(2)

  •  
  •   guonaihong ·
    guonaihong · Sep 18, 2019 · 2955 views
    This topic created in 2469 days ago, the information mentioned may be changed or developed.

    上回聊到,golang 里面写一个简单的测试函数,和 benchmark 函数,如何检测测试代码覆盖度。 这回聊下如何编写 http server 测试代码。如果写过 API 服务的童鞋都知道。 测试服务端代码要先起个服务,再运行客户端代码。有没有办法和 go test 方法结合再一起,可以很快乐的编写服务端测试代码呢?

    标准库服务端测试代码

    package main
    
    import (
        "fmt"
        "io/ioutil"
        "log"
        "net/http"
        "net/http/httptest"
    )
    
    func main() {
        // 启动一个测试服务
        ts := httptest.NewServer( http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            fmt.Fprintln(w, "Hello, client")
        })) 
        defer ts.Close()
    
        // 关键一步, 客户端完全使用标准套路,注意:url 使用 ts.URL 就行
        res, err := http.Get(ts.URL)
        if err != nil {
            log.Fatal(err)
        }   
        greeting, err := ioutil.ReadAll(res.Body)
        res.Body.Close()
        if err != nil {
            log.Fatal(err)
        }   
    
        fmt.Printf("%s", greeting)
    }
    

    gin 框架测试代码

    func TestShouldBindXML(t *testing.T) {
        var d, d2 data
        router := func() *gin.Engine {
            router := gin.Default()
    
            router.POST("/test.xml", func(c *gin.Context) {
                var d3 data
                err := c.ShouldBindXML(&d3)
                assert.NoError(t, err)
                c.XML(200, d3)
            })
            return router
        }()
    
        // 这里是 gin 和 http 标准库的区别,需要拿到 gin.Engine 的 ServeHTTP 函数
        ts := httptest.NewServer( http.HandlerFunc(router.ServeHTTP))
        defer ts.Close()
    
        g := New(nil)
    
        d.Id = 3
        d.Data = "test data"
    
        code := 200
    
        err := g.POST(ts.URL + "/test.xml").SetXML(&d).BindXML(&d2).Code(&code).Do()
    
        assert.NoError(t, err)
        assert.Equal(t, code, 200)
        assert.Equal(t, d, d2)
    }
    
    

    基于 func(w http.ResponseWriter, r *http.Request) 编写测试代码

    这个方法应用场景在编写一些库的时候会用到,只想模拟一个服务端跑 http handle 函数,里面可以设置 http header 等返回属性。然后客户端直接获得*http.Response 对象操作。可以理解为这是一个很薄薄的服务端测试写法

    func TestHeaderDecode(t *testing.T) {
        h := headerDecode{}
    
        type tHeader struct {
            Limit      int           `header:"limit"`
            F64        float64       `header:"f64"`
            F32        float32       `header:"f32"`
            CreateTime time.Time     `header:"createTime" time_format:"unixNano"`
            UnixTime   time.Time     `header:"unixTime" time_format:"unix"`
            Duration   time.Duration `header:"duration"`
        }
    
        var theader tHeader
    
        // 和正常的服务端回调函数一样
        okFunc := func(w http.ResponseWriter, r *http.Request) {
            w.Header().Add("limit", "1000")
            w.Header().Add("f64", "64")
            w.Header().Add("f32", "32.1")
            w.Header().Add("createTime", "1562400033000000123")
            w.Header().Add("unixTime", "1562400033")
            w.Header().Add("duration", "1h1s")
        }
    
        // 主要构造出 http.Request 对象
        req := httptest.NewRequest("GET", "http://example.com/foo", nil)
        // 构造出 http.ResponseWriter 对象
        w := httptest.NewRecorder()
        //执行回调函数
        okFunc(w, req)
        //构造出*http.Response 对象
        resp := w.Result()
    
        // todo array slice
        assert.NoError(t, h.Decode(resp, &theader))
    
    }
    
    

    我的 github 地址

    https://github.com/guonaihong/gout

    4 replies    2019-09-18 12:47:53 +08:00
    richzhu
        1
    richzhu  
       Sep 18, 2019
    支持,谢谢分享
    edward8628
        2
    edward8628  
       Sep 18, 2019
    感谢分享
    guonaihong
        3
    guonaihong  
    OP
       Sep 18, 2019
    @richzhu 喜欢就好,后面我会把内容整理好,做成 gitbook,方便查看。
    guonaihong
        4
    guonaihong  
    OP
       Sep 18, 2019
    @edward8628 喜欢就好。后面还会分享 go channel 相关技巧。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   5527 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 47ms · UTC 08:33 · PVG 16:33 · LAX 01:33 · JFK 04:33
    ♥ Do have faith in what you're doing.