身為一位後端工程師,如果專案初期階段不導入測試,等到專案越來越大時,您就會發現,解了一個 bug,又產生好多個額外 bug,讓產品一直處於不穩定狀態。後端最主要提供前端或手機端 RESTFul API,所以今天來介紹一套 gofight 工具,用來測試 Golang 的 http handler,讓開發者可以送 Form, JSON, Raw 資料,後端處理後,可以拿到 response 資料,透過 Testify 來測試資料是否符合需求。
目前大部份的 Golang Web Framework 都可以透過 gofight 來測試,除非作者有把
ServeHTTP
改成自己定義 Response,不然基本上都是可以支援的,我自己測試了 Gin, Mux, HttpRouter 都是可以使用的,底下來看看 gofight 該如何使用。
安裝方式
$ go get -u github.com/appleboy/gofight
-u
代表將 local 端程式碼更新到最新
使用方式
不多說直接先看例子,用 golang 基本的 http handlerpackage main import ( "io" "net/http" ) func BasicHelloHandler(w http.ResponseWriter, r *http.Request) { io.WriteString(w, "Hello World") } func BasicEngine() http.Handler { mux := http.NewServeMux() mux.HandleFunc("/", BasicHelloHandler) return mux }撰寫測試
package main import ( "github.com/appleboy/gofight" "github.com/stretchr/testify/assert" "net/http" "testing" ) func TestBasicHelloWorld(t *testing.T) { r := gofight.New() r.GET("/"). // trun on the debug mode. SetDebug(true). Run(BasicEngine(), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) { assert.Equal(t, "Hello World", r.Body.String()) assert.Equal(t, http.StatusOK, r.Code) }) }
自訂 header
透過SetHeader
可以自訂 Request header
func TestBasicHelloWorld(t *testing.T) { r := gofight.New() version := "0.0.1" r.GET("/"). // trun on the debug mode. SetDebug(true). SetHeader(gofight.H{ "X-Version": version, }). Run(BasicEngine(), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) { assert.Equal(t, version, rq.Header.Get("X-Version")) assert.Equal(t, "Hello World", r.Body.String()) assert.Equal(t, http.StatusOK, r.Code) }) }
自訂 Form Data
透過SetFORM
來傳送 Form Data
func TestPostFormData(t *testing.T) { r := gofight.New() r.POST("/form"). SetFORM(gofight.H{ "a": "1", "b": "2", }). Run(BasicEngine(), func(r HTTPResponse, rq HTTPRequest) { data := []byte(r.Body.String()) a, _ := jsonparser.GetString(data, "a") b, _ := jsonparser.GetString(data, "b") assert.Equal(t, "1", a) assert.Equal(t, "2", b) assert.Equal(t, http.StatusOK, r.Code) }) }
自訂 JSON Data
透過SetJSON
來傳送 JSON Data
func TestPostJSONData(t *testing.T) { r := gofight.New() r.POST("/json"). SetJSON(gofight.D{ "a": 1, "b": 2, }). Run(BasicEngine, func(r HTTPResponse, rq HTTPRequest) { data := []byte(r.Body.String()) a, _ := jsonparser.GetInt(data, "a") b, _ := jsonparser.GetInt(data, "b") assert.Equal(t, 1, int(a)) assert.Equal(t, 2, int(b)) assert.Equal(t, http.StatusOK, r.Code) }) }
自訂 RAW Data
透過SetBody
來傳送 RAW Data
func TestPostRawData(t *testing.T) { r := gofight.New() r.POST("/raw"). SetBody("a=1&b=1"). Run(BasicEngine, func(r HTTPResponse, rq HTTPRequest) { data := []byte(r.Body.String()) a, _ := jsonparser.GetString(data, "a") b, _ := jsonparser.GetString(data, "b") assert.Equal(t, "1", a) assert.Equal(t, "2", b) assert.Equal(t, http.StatusOK, r.Code) }) }更多測試可以直接參考 gofight_test.go 程式碼