当前位置: 首页 > 工具软件 > HttpTest > 使用案例 >

Go 自带的http测试包 httptest 使用介绍

年良骏
2023-12-01

Q:对于web的api接口如何有效的进行自测?

最偷懒的说法就是,”喂,前端开发,你页面做好了没?能不能调试下我的这个接口?“。没错,很大一部分同学是不进行自测的,都会拖到和前端进行联调的时候再测试,然后代码质量不佳的情况下,就会浪费很多联调时间

当然也有同学会说,我没这么low,我有postman,我会自己进行调试,确保提供给客户端使用联调的时候是正确的。没错,postman是个好工具,可以视图话的访问接口,甚至和很多测试平台继承进行持久化自动测试用例测试。但是你还得找个环境部署你的项目,当然本地直接启动调试服务也行。

但是我这边想介绍的是Go自带的httptest包,可以更方便的在本地开发环境下进行测试,不需要启动你的web服务就能测试

一个简单的demo

main.go:一个再简单不过的基于http包创建的web服务,提供了一个hello接口

package main

func initHttpHandler() {
    http.HandleFunc("/hello", func(w http.ResponseWriter, req *http.Request){
        response, _ := json.Marshal(map[string]string{
            "userId": req.URL.Query().Get("userId"),
            "name": req.PostFormValue("name"),
        })
        w.Write(response)
    })
}

func main() {
    initHttpHandler()
    http.ListenAndServe(":8080", nil)
}
# 启动web服务
go run main.go

# 进行接口调试
curl "http://127.0.0.1:8080/hello?userId=123" -d "name=zhangsan"    # {"name":"zhangsan","userId":"123"}

现在,介绍如何利用httptest来避开服务的启动和curl进行测试

编写一个标准的测试用力,main_test.go:

package main

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

func TestHttptest(t *testing.T) {
    initHttpHandler()

    w := httptest.NewRecorder()
    req := httptest.NewRequest("POST", "/hello?userId=123", strings.NewReader("name=zhangsan"))
    req.Header.Set("Content-type", "application/x-www-form-urlencoded")

    http.DefaultServeMux.ServeHTTP(w, req)

    fmt.Println(string(w.Body.Bytes()))
}
# 执行测试用例
go test

{"name":"zhangsan","userId":"123"}
PASS

我们并没有启动这个http的服务,直接利用了 http.DefaultServMux 这个http默认的handler来处理请求,看过http包的源码的同学应该很能理解,http.ListenAndServe 启动的时候,如果没有指定第二个参数handler,那么最终用的就是这个 DefaultServMux hanlder

同理,其他web框架比如Gin,也可以利用httptest进行单元测试,简易版main_test.go如下:

func TestHttptest(t *testing.T) {
    r := gin.Default()
    r.POST("/hello", func(c *gin.Context){
        userId := c.Query("userId")
        name := c.PostForm("name")
        c.JSON(http.StatusOK, gin.H{"userId":userId, "name":name})
    })

    w := httptest.NewRecorder()
    req := httptest.NewRequest("POST", "/hello?userId=123", strings.NewReader("name=zhangsan"))
    req.Header.Set("Content-type", "application/x-www-form-urlencoded")

    r.ServeHTTP(w, req)

    fmt.Println(string(w.Body.Bytes()))
}

 类似资料: