GitHub - appleboy/gofight: Testing API Handler written in Golang. (original) (raw)
Gofight
API Handler Testing for Golang Web framework.
Support Framework
- Http Handler Golang package http provides HTTP client and server implementations.
- Gin
- Echo support v3.0.0 up
- Mux
Install
Download this package.
go get github.com/appleboy/gofight/v2
To import this package, add the following line to your code:
import "github.com/appleboy/gofight/v2"
Usage
The following is basic testing example.
Main Program:
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 }
Testing:
package main
import ( "net/http" "testing"
"github.com/appleboy/gofight/v2" "github.com/stretchr/testify/assert" )
func TestBasicHelloWorld(t *testing.T) { r := gofight.New()
r.GET("/"). // turn 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)
})}
Set Header
You can add custom header via SetHeader func.
func TestBasicHelloWorld(t *testing.T) { r := gofight.New() version := "0.0.1"
r.GET("/"). // turn 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)
})}
POST FORM Data
Using SetForm to generate 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)
})}
POST JSON Data
Using SetJSON to generate 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)
assert.Equal(t, "application/json; charset=utf-8", r.HeaderMap.Get("Content-Type"))
})}
POST RAW Data
Using SetBody to generate 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)
})}
Set Query String
Using SetQuery to generate raw data.
func TestQueryString(t *testing.T) { r := gofight.New()
r.GET("/hello"). SetQuery(gofight.H{ "a": "1", "b": "2", }). Run(BasicEngine, func(r HTTPResponse, rq HTTPRequest) { assert.Equal(t, http.StatusOK, r.Code) }) }
or append exist query parameter.
func TestQueryString(t *testing.T) { r := gofight.New()
r.GET("/hello?foo=bar"). SetQuery(gofight.H{ "a": "1", "b": "2", }). Run(BasicEngine, func(r HTTPResponse, rq HTTPRequest) { assert.Equal(t, http.StatusOK, r.Code) }) }
Set Cookie String
Using SetCookie to generate raw data.
func TestQueryString(t *testing.T) { r := gofight.New()
r.GET("/hello"). SetCookie(gofight.H{ "foo": "bar", }). Run(BasicEngine, func(r HTTPResponse, rq HTTPRequest) { assert.Equal(t, http.StatusOK, r.Code) assert.Equal(t, "foo=bar", rq.Header.Get("cookie")) }) }
Set JSON Struct
type User struct {
// Username user name
Username string json:"username"
// Password account password
Password string json:"password"
}
func TestSetJSONInterface(t *testing.T) { r := New()
r.POST("/user"). SetJSONInterface(User{ Username: "foo", Password: "bar", }). Run(framework.GinEngine(), func(r HTTPResponse, rq HTTPRequest) { data := []byte(r.Body.String())
username := gjson.GetBytes(data, "username")
password := gjson.GetBytes(data, "password")
assert.Equal(t, "foo", username.String())
assert.Equal(t, "bar", password.String())
assert.Equal(t, http.StatusOK, r.Code)
assert.Equal(t, "application/json; charset=utf-8", r.HeaderMap.Get("Content-Type"))
})}
Upload multiple file with absolute path and parameter
The following is route using gin
func gintFileUploadHandler(c *gin.Context) { ip := c.ClientIP() hello, err := c.FormFile("hello") if err != nil { c.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) return }
helloFile, _ := hello.Open() helloBytes := make([]byte, 6) helloFile.Read(helloBytes)
world, err := c.FormFile("world") if err != nil { c.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) return }
worldFile, _ := world.Open() worldBytes := make([]byte, 6) worldFile.Read(worldBytes)
foo := c.PostForm("foo") bar := c.PostForm("bar") c.JSON(http.StatusOK, gin.H{ "hello": hello.Filename, "world": world.Filename, "foo": foo, "bar": bar, "ip": ip, "helloSize": string(helloBytes), "worldSize": string(worldBytes), }) }
Write the testing:
func TestUploadFile(t *testing.T) { r := New()
r.POST("/upload"). SetDebug(true). SetFileFromPath([]UploadFile{ { Path: "./testdata/hello.txt", Name: "hello", }, { Path: "./testdata/world.txt", Name: "world", }, }, H{ "foo": "bar", "bar": "foo", }). Run(framework.GinEngine(), func(r HTTPResponse, rq HTTPRequest) { data := []byte(r.Body.String())
hello := gjson.GetBytes(data, "hello")
world := gjson.GetBytes(data, "world")
foo := gjson.GetBytes(data, "foo")
bar := gjson.GetBytes(data, "bar")
ip := gjson.GetBytes(data, "ip")
helloSize := gjson.GetBytes(data, "helloSize")
worldSize := gjson.GetBytes(data, "worldSize")
assert.Equal(t, "world\n", helloSize.String())
assert.Equal(t, "hello\n", worldSize.String())
assert.Equal(t, "hello.txt", hello.String())
assert.Equal(t, "world.txt", world.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"))
})}
Upload multiple file with content []byte path and parameter
func TestUploadFileByContent(t *testing.T) { r := New()
helloContent, err := ioutil.ReadFile("./testdata/hello.txt") if err != nil { log.Fatal(err) }
worldContent, err := ioutil.ReadFile("./testdata/world.txt") if err != nil { log.Fatal(err) }
r.POST("/upload"). SetDebug(true). SetFileFromPath([]UploadFile{ { Path: "hello.txt", Name: "hello", Content: helloContent, }, { Path: "world.txt", Name: "world", Content: worldContent, }, }, H{ "foo": "bar", "bar": "foo", }). Run(framework.GinEngine(), func(r HTTPResponse, rq HTTPRequest) { data := []byte(r.Body.String())
hello := gjson.GetBytes(data, "hello")
world := gjson.GetBytes(data, "world")
foo := gjson.GetBytes(data, "foo")
bar := gjson.GetBytes(data, "bar")
ip := gjson.GetBytes(data, "ip")
helloSize := gjson.GetBytes(data, "helloSize")
worldSize := gjson.GetBytes(data, "worldSize")
assert.Equal(t, "world\n", helloSize.String())
assert.Equal(t, "hello\n", worldSize.String())
assert.Equal(t, "hello.txt", hello.String())
assert.Equal(t, "world.txt", world.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"))
})}
Example
License
Copyright 2019 Bo-Yi Wu @appleboy.
Licensed under the MIT License.