{"id":37178329,"url":"https://github.com/rohmanhm/gofight","last_synced_at":"2026-01-14T20:47:00.164Z","repository":{"id":57552352,"uuid":"159008988","full_name":"rohmanhm/gofight","owner":"rohmanhm","description":"Testing API Handler written in Golang.","archived":false,"fork":true,"pushed_at":"2018-11-26T14:21:08.000Z","size":1077,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-05T14:03:33.987Z","etag":null,"topics":["golang","testing","testing-tools"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"appleboy/gofight","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rohmanhm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-11-25T07:38:59.000Z","updated_at":"2018-11-25T16:04:24.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/rohmanhm/gofight","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/rohmanhm/gofight","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rohmanhm%2Fgofight","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rohmanhm%2Fgofight/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rohmanhm%2Fgofight/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rohmanhm%2Fgofight/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rohmanhm","download_url":"https://codeload.github.com/rohmanhm/gofight/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rohmanhm%2Fgofight/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28434500,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T18:57:19.464Z","status":"ssl_error","status_checked_at":"2026-01-14T18:52:48.501Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["golang","testing","testing-tools"],"created_at":"2026-01-14T20:46:59.384Z","updated_at":"2026-01-14T20:47:00.124Z","avatar_url":"https://github.com/rohmanhm.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Gofight\n\n[![GoDoc](https://godoc.org/github.com/rohmanhm/gofight?status.svg)](https://godoc.org/github.com/rohmanhm/gofight) [![Build Status](https://travis-ci.org/appleboy/gofight.svg?branch=master)](https://travis-ci.org/appleboy/gofight) [![Go Report Card](https://goreportcard.com/badge/github.com/rohmanhm/gofight)](https://goreportcard.com/report/github.com/rohmanhm/gofight) [![codebeat badge](https://codebeat.co/badges/4d8b58ae-67ec-469e-bde6-be3dd336b30d)](https://codebeat.co/projects/github-com-appleboy-gofight) [![codecov](https://codecov.io/gh/appleboy/gofight/branch/master/graph/badge.svg)](https://codecov.io/gh/appleboy/gofight) [![Sourcegraph](https://sourcegraph.com/github.com/rohmanhm/gofight/-/badge.svg)](https://sourcegraph.com/github.com/rohmanhm/gofight?badge)\n\nAPI Handler Testing for Golang Web framework.\n\n## Support Framework\n\n* [x] [Http Handler](https://golang.org/pkg/net/http/) Golang package http provides HTTP client and server implementations.\n* [x] [Gin](https://github.com/gin-gonic/gin)\n* [x] [Echo](https://github.com/labstack/echo) support [v3.0.0](https://github.com/labstack/echo/releases/tag/v3.0.0) up\n* [x] [Mux](https://github.com/gorilla/mux)\n* [x] [HttpRouter](https://github.com/julienschmidt/httprouter)\n* [x] [Pat](https://github.com/gorilla/pat)\n\n## Usage\n\nDownload this package.\n\n```bash\n$ go get github.com/rohmanhm/gofight\n```\n\nTo import this package, add the following line to your code:\n\n```go\nimport \"github.com/rohmanhm/gofight\"\n```\n\n## Usage\n\nThe following is basic testing example.\n\nMain Program:\n\n```go\npackage main\n\nimport (\n  \"io\"\n  \"net/http\"\n)\n\nfunc BasicHelloHandler(w http.ResponseWriter, r *http.Request) {\n  io.WriteString(w, \"Hello World\")\n}\n\nfunc BasicEngine() http.Handler {\n  mux := http.NewServeMux()\n  mux.HandleFunc(\"/\", BasicHelloHandler)\n\n  return mux\n}\n```\n\nTesting:\n\n```go\npackage main\n\nimport (\n  \"github.com/rohmanhm/gofight\"\n  \"github.com/stretchr/testify/assert\"\n  \"net/http\"\n  \"testing\"\n)\n\nfunc TestBasicHelloWorld(t *testing.T) {\n  r := gofight.New()\n\n  r.GET(\"/\").\n    // turn on the debug mode.\n    SetDebug(true).\n    Run(BasicEngine(), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {\n\n      assert.Equal(t, \"Hello World\", r.Body.String())\n      assert.Equal(t, http.StatusOK, r.Code)\n    })\n}\n```\n\n### Set Header\n\nYou can add custom header via `SetHeader` func.\n\n```go\nfunc TestBasicHelloWorld(t *testing.T) {\n  r := gofight.New()\n  version := \"0.0.1\"\n\n  r.GET(\"/\").\n    // turn on the debug mode.\n    SetDebug(true).\n    SetHeader(gofight.H{\n      \"X-Version\": version,\n    }).\n    Run(BasicEngine(), func(r gofight.HTTPResponse, rq gofight.HTTPRequest) {\n\n      assert.Equal(t, version, rq.Header.Get(\"X-Version\"))\n      assert.Equal(t, \"Hello World\", r.Body.String())\n      assert.Equal(t, http.StatusOK, r.Code)\n    })\n}\n```\n\n### POST FORM Data\n\nUsing `SetForm` to generate form data.\n\n```go\nfunc TestPostFormData(t *testing.T) {\n  r := gofight.New()\n\n  r.POST(\"/form\").\n    SetForm(gofight.H{\n      \"a\": \"1\",\n      \"b\": \"2\",\n    }).\n    Run(BasicEngine(), func(r HTTPResponse, rq HTTPRequest) {\n      data := []byte(r.Body.String())\n\n      a, _ := jsonparser.GetString(data, \"a\")\n      b, _ := jsonparser.GetString(data, \"b\")\n\n      assert.Equal(t, \"1\", a)\n      assert.Equal(t, \"2\", b)\n      assert.Equal(t, http.StatusOK, r.Code)\n    })\n}\n```\n\n### POST JSON Data\n\nUsing `SetJSON` to generate JSON data.\n\n```go\nfunc TestPostJSONData(t *testing.T) {\n  r := gofight.New()\n\n  r.POST(\"/json\").\n    SetJSON(gofight.D{\n      \"a\": 1,\n      \"b\": 2,\n    }).\n    Run(BasicEngine, func(r HTTPResponse, rq HTTPRequest) {\n      data := []byte(r.Body.String())\n\n      a, _ := jsonparser.GetInt(data, \"a\")\n      b, _ := jsonparser.GetInt(data, \"b\")\n\n      assert.Equal(t, 1, int(a))\n      assert.Equal(t, 2, int(b))\n      assert.Equal(t, http.StatusOK, r.Code)\n      assert.Equal(t, \"application/json; charset=utf-8\", r.HeaderMap.Get(\"Content-Type\"))\n    })\n}\n```\n\n### POST RAW Data\n\nUsing `SetBody` to generate raw data.\n\n```go\nfunc TestPostRawData(t *testing.T) {\n  r := gofight.New()\n\n  r.POST(\"/raw\").\n    SetBody(\"a=1\u0026b=1\").\n    Run(BasicEngine, func(r HTTPResponse, rq HTTPRequest) {\n      data := []byte(r.Body.String())\n\n      a, _ := jsonparser.GetString(data, \"a\")\n      b, _ := jsonparser.GetString(data, \"b\")\n\n      assert.Equal(t, \"1\", a)\n      assert.Equal(t, \"2\", b)\n      assert.Equal(t, http.StatusOK, r.Code)\n    })\n}\n```\n\n### Set Query String\n\nUsing `SetQuery` to generate raw data.\n\n```go\nfunc TestQueryString(t *testing.T) {\n  r := gofight.New()\n\n  r.GET(\"/hello\").\n    SetQuery(gofight.H{\n      \"a\": \"1\",\n      \"b\": \"2\",\n    }).\n    Run(BasicEngine, func(r HTTPResponse, rq HTTPRequest) {\n      assert.Equal(t, http.StatusOK, r.Code)\n    })\n}\n```\n\nor append exist query parameter.\n\n```go\nfunc TestQueryString(t *testing.T) {\n  r := gofight.New()\n\n  r.GET(\"/hello?foo=bar\").\n    SetQuery(gofight.H{\n      \"a\": \"1\",\n      \"b\": \"2\",\n    }).\n    Run(BasicEngine, func(r HTTPResponse, rq HTTPRequest) {\n      assert.Equal(t, http.StatusOK, r.Code)\n    })\n}\n```\n\n### Set Cookie String\n\nUsing `SetCookie` to generate raw data.\n\n```go\nfunc TestQueryString(t *testing.T) {\n  r := gofight.New()\n\n  r.GET(\"/hello\").\n    SetCookie(gofight.H{\n      \"foo\": \"bar\",\n    }).\n    Run(BasicEngine, func(r HTTPResponse, rq HTTPRequest) {\n      assert.Equal(t, http.StatusOK, r.Code)\n      assert.Equal(t, \"foo=bar\", rq.Header.Get(\"cookie\"))\n    })\n}\n```\n\n### Set JSON Struct\n\n```go\ntype User struct {\n\t// Username user name\n\tUsername string `json:\"username\"`\n\t// Password account password\n\tPassword string `json:\"password\"`\n}\n\nfunc TestSetJSONInterface(t *testing.T) {\n\tr := New()\n\n\tr.POST(\"/user\").\n\t\tSetJSONInterface(User{\n\t\t\tUsername: \"foo\",\n\t\t\tPassword: \"bar\",\n\t\t}).\n\t\tRun(framework.GinEngine(), func(r HTTPResponse, rq HTTPRequest) {\n\t\t\tdata := []byte(r.Body.String())\n\n\t\t\tusername := gjson.GetBytes(data, \"username\")\n\t\t\tpassword := gjson.GetBytes(data, \"password\")\n\n\t\t\tassert.Equal(t, \"foo\", username.String())\n\t\t\tassert.Equal(t, \"bar\", password.String())\n\t\t\tassert.Equal(t, http.StatusOK, r.Code)\n\t\t\tassert.Equal(t, \"application/json; charset=utf-8\", r.HeaderMap.Get(\"Content-Type\"))\n\t\t})\n}\n```\n\n### Upload multiple file with absolute path and parameter\n\nThe following is route using gin\n\n```go\nfunc gintFileUploadHandler(c *gin.Context) {\n\tip := c.ClientIP()\n\thello, err := c.FormFile(\"hello\")\n\tif err != nil {\n\t\tc.JSON(http.StatusBadRequest, gin.H{\n\t\t\t\"error\": err.Error(),\n\t\t})\n\t\treturn\n\t}\n\n\thelloFile, _ := hello.Open()\n\thelloBytes := make([]byte, 6)\n\thelloFile.Read(helloBytes)\n\n\tworld, err := c.FormFile(\"world\")\n\tif err != nil {\n\t\tc.JSON(http.StatusBadRequest, gin.H{\n\t\t\t\"error\": err.Error(),\n\t\t})\n\t\treturn\n\t}\n\n\tworldFile, _ := world.Open()\n\tworldBytes := make([]byte, 6)\n\tworldFile.Read(worldBytes)\n\n\tfoo := c.PostForm(\"foo\")\n\tbar := c.PostForm(\"bar\")\n\tc.JSON(http.StatusOK, gin.H{\n\t\t\"hello\":     hello.Filename,\n\t\t\"world\":     world.Filename,\n\t\t\"foo\":       foo,\n\t\t\"bar\":       bar,\n\t\t\"ip\":        ip,\n\t\t\"helloSize\": string(helloBytes),\n\t\t\"worldSize\": string(worldBytes),\n\t})\n}\n```\n\nWrite the testing:\n\n```go\nfunc TestUploadFile(t *testing.T) {\n\tr := New()\n\n\tr.POST(\"/upload\").\n\t\tSetDebug(true).\n\t\tSetFileFromPath([]UploadFile{\n\t\t\t{\n\t\t\t\tPath: \"./testdata/hello.txt\",\n\t\t\t\tName: \"hello\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tPath: \"./testdata/world.txt\",\n\t\t\t\tName: \"world\",\n\t\t\t},\n\t\t}, H{\n\t\t\t\"foo\": \"bar\",\n\t\t\t\"bar\": \"foo\",\n\t\t}).\n\t\tRun(framework.GinEngine(), func(r HTTPResponse, rq HTTPRequest) {\n\t\t\tdata := []byte(r.Body.String())\n\n\t\t\thello := gjson.GetBytes(data, \"hello\")\n\t\t\tworld := gjson.GetBytes(data, \"world\")\n\t\t\tfoo := gjson.GetBytes(data, \"foo\")\n\t\t\tbar := gjson.GetBytes(data, \"bar\")\n\t\t\tip := gjson.GetBytes(data, \"ip\")\n\t\t\thelloSize := gjson.GetBytes(data, \"helloSize\")\n\t\t\tworldSize := gjson.GetBytes(data, \"worldSize\")\n\n\t\t\tassert.Equal(t, \"world\\n\", helloSize.String())\n\t\t\tassert.Equal(t, \"hello\\n\", worldSize.String())\n\t\t\tassert.Equal(t, \"hello.txt\", hello.String())\n\t\t\tassert.Equal(t, \"world.txt\", world.String())\n\t\t\tassert.Equal(t, \"bar\", foo.String())\n\t\t\tassert.Equal(t, \"foo\", bar.String())\n\t\t\tassert.Equal(t, \"\", ip.String())\n\t\t\tassert.Equal(t, http.StatusOK, r.Code)\n\t\t\tassert.Equal(t, \"application/json; charset=utf-8\", r.HeaderMap.Get(\"Content-Type\"))\n\t\t})\n}\n```\n\n### Upload multiple file with content `[]byte` path and parameter\n\n```go\nfunc TestUploadFileByContent(t *testing.T) {\n\tr := New()\n\n\thelloContent, err := ioutil.ReadFile(\"./testdata/hello.txt\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tworldContent, err := ioutil.ReadFile(\"./testdata/world.txt\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tr.POST(\"/upload\").\n\t\tSetDebug(true).\n\t\tSetFileFromPath([]UploadFile{\n\t\t\t{\n\t\t\t\tPath:    \"hello.txt\",\n\t\t\t\tName:    \"hello\",\n\t\t\t\tContent: helloContent,\n\t\t\t},\n\t\t\t{\n\t\t\t\tPath:    \"world.txt\",\n\t\t\t\tName:    \"world\",\n\t\t\t\tContent: worldContent,\n\t\t\t},\n\t\t}, H{\n\t\t\t\"foo\": \"bar\",\n\t\t\t\"bar\": \"foo\",\n\t\t}).\n\t\tRun(framework.GinEngine(), func(r HTTPResponse, rq HTTPRequest) {\n\t\t\tdata := []byte(r.Body.String())\n\n\t\t\thello := gjson.GetBytes(data, \"hello\")\n\t\t\tworld := gjson.GetBytes(data, \"world\")\n\t\t\tfoo := gjson.GetBytes(data, \"foo\")\n\t\t\tbar := gjson.GetBytes(data, \"bar\")\n\t\t\tip := gjson.GetBytes(data, \"ip\")\n\t\t\thelloSize := gjson.GetBytes(data, \"helloSize\")\n\t\t\tworldSize := gjson.GetBytes(data, \"worldSize\")\n\n\t\t\tassert.Equal(t, \"world\\n\", helloSize.String())\n\t\t\tassert.Equal(t, \"hello\\n\", worldSize.String())\n\t\t\tassert.Equal(t, \"hello.txt\", hello.String())\n\t\t\tassert.Equal(t, \"world.txt\", world.String())\n\t\t\tassert.Equal(t, \"bar\", foo.String())\n\t\t\tassert.Equal(t, \"foo\", bar.String())\n\t\t\tassert.Equal(t, \"\", ip.String())\n\t\t\tassert.Equal(t, http.StatusOK, r.Code)\n\t\t\tassert.Equal(t, \"application/json; charset=utf-8\", r.HeaderMap.Get(\"Content-Type\"))\n\t\t})\n}\n```\n\n## Example\n\n* Basic HTTP Router: [basic.go](example/basic.go), [basic_test.go](example/basic_test.go)\n* Gin Framework: [gin.go](example/gin.go), [gin_test.go](example/gin_test.go)\n* Echo Framework: [echo.go](example/echo.go), [echo_test.go](example/echo_test.go)\n* Mux Framework: [mux.go](example/mux.go), [mux_test.go](example/mux_test.go)\n* HttpRouter Framework: [httprouter.go](example/httprouter.go), [httprouter_test.go](example/httprouter_test.go)\n\n## Testing\n\n```\n$ make\n```\n\n## License\n\nCopyright 2018 Bo-Yi Wu [@appleboy](https://twitter.com/appleboy).\n\nLicensed under the MIT License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frohmanhm%2Fgofight","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frohmanhm%2Fgofight","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frohmanhm%2Fgofight/lists"}