**原文來自: [用 gofight 來測試 golang web API handler](https://blog.wu-boy.com/2016/04/gofight-tool-for-api-handler-testing-in-golang/)**
身為一位後端工程師,如果專案初期階段不導入測試,等到專案越來越大時,您就會發現,解了一個 bug,又產生好多個額外 bug,讓產品一直處於不穩定狀態。後端最主要提供前端或手機端 RESTFul API,所以今天來介紹一套 [gofight][2] 工具,用來測試 [Golang][1] 的 http [handler](https://golang.org/pkg/net/http/#Handler),讓開發者可以送 Form, JSON, Raw 資料,後端處理後,可以拿到 response 資料,透過 [Testify][3] 來測試資料是否符合需求。
目前大部份的 Golang Web Framework 都可以透過 [gofight][2] 來測試,除非作者有把 `ServeHTTP` 改成自己定義 Response,不然基本上都是可以支援的,我自己測試了 [Gin](https://github.com/gin-gonic/gin), [Mux](https://github.com/gorilla/mux), [HttpRouter](https://github.com/julienschmidt/httprouter) 都是可以使用的,底下來看看 [gofight][2] 該如何使用。
<!--more-->
## 安裝方式
```
$ go get -u github.com/appleboy/gofight
```
`-u` 代表將 local 端程式碼更新到最新
## 使用方式
不多說直接先看例子,用 golang 基本的 http handler
```go
package 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
}
```
撰寫測試
```go
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
```go
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
```go
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
```go
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
```go
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](https://github.com/appleboy/gofight/blob/master/gofight_test.go) 程式碼
[1]:https://golang.org/
[2]:https://github.com/appleboy/gofight
[3]:https://github.com/stretchr/testify
有疑问加站长微信联系(非本文作者)