Golang gin路由函数测试模板:
package handler
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"os"
"testing"
"内部log库和mock库可以替换成外部log库和gomonkey库"
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/assert"
)
func setup() {
log.Info("setup started")
defer log.Info("setup completed")
}
func teardown() {
log.Info("teardown started")
defer log.Info("teardown completed")
}
func TestMain(m *testing.M) {
setup()
code := m.Run()
teardown()
os.Exit(code)
}
// testHTTPResponse 是一个发起请求并测试其返回的辅助函数
// https://semaphoreci.com/community/tutorials/building-go-web-applications-and-microservices-using-gin
func testHTTPResponse(t *testing.T, r *gin.Engine, req *http.Request, f func(w *httptest.ResponseRecorder) bool) {
// 创建一个response接收体
w := httptest.NewRecorder()
// 创建服务并请求
r.ServeHTTP(w, req)
if !f(w) {
t.Fail()
}
}
// newReq 创建请求
func newReq(method ReqMethod, reqURL string, params map[string]string) (*http.Request, error) {
paramsBytes, err := json.Marshal(params)
if err != nil {
return nil, fmt.Errorf("error marshal json->%+v", err)
}
r, newReqErr := http.NewRequest(string(method), reqURL, bytes.NewBuffer(paramsBytes))
if newReqErr != nil {
return nil, fmt.Errorf("error %+v request %+v->%+v", method, reqURL, err)
}
return r, nil
}
// ReqMethod 请求方法
type ReqMethod string
// 常量
const (
Get ReqMethod = "GET" // Get请求
Post ReqMethod = "POST" // Post请求
)
func TestUploadProjectIconHandlerValid(t *testing.T) {
reqURL := "some/router/url"
// Mock
mock := mocker.Create()
defer mock.Reset()
// 待测gin路由准备
testGinRouter := gin.Default()
testGinRouter.POST(reqURL, RouterFunction)
// 定义测试用例参数
type args struct {
reqParams map[string]string
customStub func()
}
// 定义测试用例预期结果
type want struct {
code int
msg string
}
// 定义并初始化测试用例
tests := []struct {
name string
args args
want want
}{...}
// 遍历用例
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// 自定义stub过程
tt.args.customStub()
// 模拟请求
testReq, err := newReq(Post, reqURL, tt.args.reqParams)
assert.Nil(t, err)
// 测试gin框架路由http请求
testHTTPResponse(t, testGinRouter, testReq, func(w *httptest.ResponseRecorder) bool {
log.Infof("%+v", w.Body.String())
assert.Equal(t, tt.want.code, w.Code)
assert.Equal(t, tt.want.msg, w.Body.String())
return true
})
// 重置mock
mock.Reset()
})
}
}