在寫完接口以後都須要對接口進行測試,在 golang 標準庫中提供 httptest
包來輔助測試。golang
由於接口都是須要 IP 地址或域名來訪問,httptest
包中默認定義了服務地址json
const DefaultRemoteAddr = "1.2.3.4"
NewRequest
方法用來建立一個 http 的請求體。api
方法定義:app
func NewRequest(method, target string, body io.Reader) *http.Request
method
參數表示測試的接口的 HTTP 方法。target
參數表示接口定義的路由。body
參數表示請求體。方法定義:框架
func NewRecorder() *ResponseRecorder
NewRecorder 方法用來建立 http 的響應體。返回的類型是 *httptest.ResponseRecorder
,包含接口返回信息,等價於 http.ResponseWriter
。單元測試
ResponseRecorder類型定義:測試
type ResponseRecorder struct { // http 響應碼. Code int // 頭部信息 HeaderMap http.Header // 返回的 Body Body *bytes.Buffer // 是否調用 Flush 方法 Flushed bool }
方法定義:code
func NewServer(handler http.Handler) *Server
NewServer 方法用來建立和啓動新的服務。同類的還有 NewTLSServer,用來建立帶 SSL 的服務。router
type Server struct { URL string // 服務地址 Listener net.Listener // TLS 配置信息 TLS *tls.Config Config *http.Server }
請求接口定義:server
func testAPI(w http.ResponseWriter, r *http.Request){}
測試方法定義:
func Test_testApi(t *testing.T) { tests := []struct { name string }{ { name: "test api", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(testAPI)) defer ts.Close() params := struct{ "params" string }{ "params": "paramsBody" } paramsByte, _ := json.Marshal(params) resp, err := http.Post(tserver.URL, "application/json", bytes.NewBuffer(paramsByte)) if err != nil { t.Error(err) } defer resp.Body.Close() t.Log(resp.StatusCode) if resp.StatusCode != http.StatusCreated && resp.StatusCode != http.StatusOK { body, _ := ioutil.ReadAll(resp.Body) t.Error(string(body)) } }) } }
測試時經過 httptest.NewServer
建立一個 testAPI 接口的服務。而後經過 http.Post 方法來調用咱們建立的服務,達到接口測試時請求的目的。而後判斷接口返回的信息是否正確。
請求接口定義:
func testAPI(ctx *gin.Context){}
測試方法定義:
func Test_testAPI(t *testing.T) { // 定義路由 router := gin.Default() router.POST("/test", testAPI) tests := []struct { name string }{ { name: "test api", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { params := struct{ "params" string }{ "params": "paramsBody" } paramsByte, _ := json.Marshal(params) w := httptest.NewRecorder() req := httptest.NewRequest("POST", "/test", bytes.NewBuffer(paramsByte)) setup.api.router.ServeHTTP(w, req) assert.Equal(t, http.StatusOK, w.Code) result, _ := ioutil.ReadAll(w.Body) var ret model.MessageResult if err := json.Unmarshal(result, &ret); err != nil { t.Error(err) } assert.Equal(t, tt.want, ret) }) } }
測試時須要定義好 gin 的路由,而後建立 httptest.NewRecorder 和 httptest.NewRequest 對象,並調用 gin 路由的 ServeHTTP 方法來執行接口。
ServeHTTP 是 *gin.Engine 實現了 http.Handler
接口。經過這種方式達到請求接口目的。而後判斷接口返回的信息是否正確。
接口的測試在開發當中是十分重要,我這裏介紹了使用 net/http 和 gin 建立接口的測試用例。
經過 httptest 包能方便的對接口進行單元測試,而不須要單獨的起一個服務來進行測試。