gofight 是一套用 Go 語言撰寫的 HTTP API 測試套件,之前已經寫過一篇介紹用法,當時候尚未支援檔案上傳測試,也就是假設寫了一個檔案上傳的 http handler 在專案內如何寫測試,底下來看看該如何使用。
準備環境
首先需要一個測試檔案,通常會在專案底下建立testdata
目錄,裡面放置一個叫 hello.txt
檔案,內容為 world
。接著安裝 gofight
套件,可以用團隊內喜愛的 vendor 工具,我個人偏好 govendor:
$ govendor fetch github.com/kardianos/govendor 或 $ go get -u github.com/kardianos/govendor
檔案上傳範例
這邊用 gin 框架當作範例,如果您用其他框架只要支援http.HandlerFunc
都可以使用。
func gintFileUploadHandler(c *gin.Context) { ip := c.ClientIP() file, err := c.FormFile("test") if err != nil { c.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) return } foo := c.PostForm("foo") bar := c.PostForm("bar") c.JSON(http.StatusOK, gin.H{ "hello": "world", "filename": file.Filename, "foo": foo, "bar": bar, "ip": ip, }) } // GinEngine is gin router. func GinEngine() *gin.Engine { gin.SetMode(gin.TestMode) r := gin.New() r.POST("/upload", gintFileUploadHandler) return r }上面例子可以發現,測試端需要傳兩個 post 參數,加上一個檔案 (檔名為 test),底下看看 gofight 怎麼寫測試。
檔案上傳測試
gofight 現在支援一個函式叫SetFileFromPath
此 func 支援三個參數。
- 檔案讀取路徑
- POST 檔案名稱
- POST 參數
testdata/hello.txt
那該參數就是填寫 testdata/hello.txt
,請注意這是相對於 *_test.go
檔案路徑,第二個參數就是定義該檔案的 post 參數,請依照 handler 內的 c.FormFile("test")
來決定變數名稱,第三個參數可有可無,也就是檔案上傳頁面,可能會需要上傳其他 post 參數,這時候就要寫在第三個參數,看底下實際例子:
func TestUploadFile(t *testing.T) { r := New() r.POST("/upload"). SetFileFromPath("fixtures/hello.txt", "test", H{ "foo": "bar", "bar": "foo", }). Run(framework.GinEngine(), func(r HTTPResponse, rq HTTPRequest) { data := []byte(r.Body.String()) hello := gjson.GetBytes(data, "hello") filename := gjson.GetBytes(data, "filename") foo := gjson.GetBytes(data, "foo") bar := gjson.GetBytes(data, "bar") ip := gjson.GetBytes(data, "ip") assert.Equal(t, "world", hello.String()) assert.Equal(t, "hello.txt", filename.String()) assert.Equal(t, "bar", foo.String()) assert.Equal(t, "foo", bar.String()) assert.Equal(t, "", ip.String()) assert.Equal(t, http.StatusOK, r.Code) assert.Equal(t, "application/json; charset=utf-8", r.HeaderMap.Get("Content-Type")) }) }可以看到上面例子正確拿到檔案上傳資料,並且測試成功。