Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

htest is a http-test package

License

NotificationsYou must be signed in to change notification settings

Hexilee/htest

Repository files navigation

Coverage StatusGo Report CardBuild StatusLicense: MITDocumentation

Table of Contents

Basic Usage


Test MockServer

Test a Handler or a HandlerFunc

Test HandlerFunc
// example/basic_mock_client.gopackage myappimport ("io""net/http")funcNameHandler(w http.ResponseWriter,req*http.Request) {io.WriteString(w,`{"name": "hexi"}`)}
// example/basic_mock_client_test.gopackage myappimport ("testing""github.com/Hexilee/htest")funcTestNameHandlerFunc(t*testing.T) {htest.NewClient(t).ToFunc(NameHandler).Get("").Test().StatusOK().JSON().String("name","hexi")}

You can also test handler (*http.ServeMux, *echo.Echo .etc.)

To ServeMux
// example/basic_mock_client.gopackage myappimport ("io""net/http")var (Mux*http.ServeMux)funcinit() {Mux=http.NewServeMux()Mux.HandleFunc("/name",NameHandler)}funcNameHandler(w http.ResponseWriter,req*http.Request) {io.WriteString(w,`{"name": "hexi"}`)}
// example/basic_mock_client_test.gopackage myappimport ("testing""github.com/Hexilee/htest")funcTestNameHandler(t*testing.T) {htest.NewClient(t).To(Mux).Get("/name").Test().StatusOK().JSON().String("name","hexi")}
To Echo
// example/basic_mock_client.gopackage myappimport ("io""github.com/labstack/echo")var (server*echo.Echo)funcinit() {server=echo.New()server.GET("/name",NameHandlerEcho)}funcNameHandlerEcho(c echo.Context)error {returnc.String(http.StatusOK,`{"name": "hexi"}`)}
// example/basic_mock_client_test.gopackage myappimport ("testing""github.com/Hexilee/htest")funcTestNameHandlerEcho(t*testing.T) {htest.NewClient(t).To(server).Get("/name").Test().StatusOK().JSON().String("name","hexi")}

Test RealServer

Send a http request and test the response

Github API
// request_test.gofuncTestRequest_Send(t*testing.T) {NewClient(t).Get("https://api.github.com/users/Hexilee").Send().StatusOK().JSON().String("login","Hexilee")}

Client


Set MockServer

Set mock server to be tested (Do not need it when you test real server)

HandlerFunc

Set a HandlerFunc as mock server

// example/basic_mock_client_test.gopackage myappimport ("testing""github.com/Hexilee/htest")funcTestNameHandlerFunc(t*testing.T) {htest.NewClient(t).ToFunc(NameHandler).Get("").Test().StatusOK().JSON().String("name","hexi")}
Handler

Set a Handler as mock server

// example/basic_mock_client_test.gopackage myappimport ("testing""github.com/Hexilee/htest")funcTestNameHandler(t*testing.T) {htest.NewClient(t).To(Mux).Get("/name").Test().StatusOK().JSON().String("name","hexi")}

Construct Request

Construct htest.Request using different http methods

Http Methods

For example

  • Get
// client.gofunc (cClient)Get(pathstring)*Request

More

  • Head
  • Trace
  • Options
  • Connect
  • Delete
  • Post
  • Put
  • Patch

Request


Set Headers

Set headers and return *Request for chaining-call

  • SetHeader
// server_test.goMux.Get("/request/header",HeaderHandler)// request_test.gofuncHeaderHandler(w http.ResponseWriter,req*http.Request) {ifreq.Header.Get(HeaderContentType)==MIMEApplicationJSON {io.WriteString(w,`{"result": "JSON"}`)return}http.Error(w,http.StatusText(http.StatusBadRequest),http.StatusBadRequest)}funcTestRequest_SetHeader(t*testing.T) {client:=NewClient(t).To(Mux)// bad content typeclient.Get("/request/header").SetHeader(HeaderContentType,MIMEApplicationForm).Test().StatusBadRequest()// rightclient.Get("/request/header").SetHeader(HeaderContentType,MIMEApplicationJSON).Test().StatusOK().JSON().String("result","JSON")}

HeaderContentType, MIMEApplicationForm are constants in const.goFor more information, you can refer toAppendix

  • SetHeaders
// request_test.gofuncTestRequest_SetHeaders(t*testing.T) {client:=NewClient(t).To(Mux)// bad content typeclient.Get("/request/header").SetHeaders(map[string]string{HeaderContentType:MIMEApplicationForm,},).Test().StatusBadRequest()// rightclient.Get("/request/header").SetHeaders(map[string]string{HeaderContentType:MIMEApplicationJSON,},).Test().StatusOK().JSON().String("result","JSON")}

Add Cookie

Add cookie and return *Request for chaining-call

// server_test.goMux.Get("/request/cookie",CookieHandler)// request_test.govar (testCookie= http.Cookie{Name:"test_cookie",Value:"cookie_value"})funcCookieHandler(w http.ResponseWriter,req*http.Request) {cookie,err:=req.Cookie(testCookie.Name)iferr!=nil {http.Error(w,http.StatusText(http.StatusForbidden),http.StatusForbidden)return}io.WriteString(w,fmt.Sprintf(`{"cookie": "%s"}`,cookie))}funcTestRequest_AddCookie(t*testing.T) {client:=NewClient(t).To(Mux)client.Get("/request/cookie").Test().StatusForbidden()client.Get("/request/cookie").AddCookie(&testCookie).Test().StatusOK().JSON().String("cookie",testCookie.String())}

Test

Calling *Request.Test will test the mock server and return a *Response.

You must have called Client.To or Client.ToFunc, otherwise causing a panic (htest.MockNilError)

// request_test.gofuncTestRequest_Test(t*testing.T) {deferfunc() {assert.Equal(t,MockNilError,recover())}()NewClient(t).Get("/request/header").SetHeader(HeaderContentType,MIMEApplicationForm).Test().StatusBadRequest()}

Send

Calling *Request.Send will send a real http request and return a *Response

// request_test.gofuncTestRequest_Send(t*testing.T) {NewClient(t).Get("https://api.github.com/users/Hexilee").Send().StatusOK().JSON().String("login","Hexilee")}

As http.Request

As *http.Request is embedded in htest.Request, you can regard *htest.Request as *http.Request. Just like:

userAgent:=NewClient(t).Get("https://api.github.com/users/Hexilee").UserAgent()

Response


Assert StatusCode

Assert Response.StatusCode

Code

*Response.Code(statusCode int)

// response_test.govar (ResponseCodeServer=chi.NewRouter())funcinit() {ResponseCodeServer.Get("/response/statusCode/{code}",StatusHandler)}funcStatusHandler(w http.ResponseWriter,req*http.Request) {codeStr:=chi.URLParam(req,"code")code,err:=strconv.Atoi(codeStr)iferr!=nil {w.WriteHeader(http.StatusNotFound)return}w.WriteHeader(code)}funcTestResponse_Code(t*testing.T) {NewClient(t).To(ResponseCodeServer).Get(fmt.Sprintf("/response/statusCode/%d",http.StatusBadRequest)).Test().Code(http.StatusBadRequest)}
StatusXXX

For more ergonomic development, *htest.Response has many methods to assert all the StatusCode in net/http

// response_test.gofuncTestResponse_StatusContinue(t*testing.T) {NewClient(t).To(ResponseCodeServer).Get(fmt.Sprintf("/response/statusCode/%d",http.StatusContinue)).Test().StatusContinue()}

Assert Headers

Assert Response.Headlers

Headers

*Response.Headers(key, expect string)

// response_test.govar (ResponseHeadersServer=chi.NewRouter())funcinit() {ResponseHeadersServer.Get("/response/headers",HeadersHandler)}funcHeadersHandler(w http.ResponseWriter,req*http.Request) {query:=req.URL.Query()header:=query.Get("header")value:=query.Get("value")w.Header().Set(header,value)}funcTestResponse_Headers(t*testing.T) {url:=fmt.Sprintf("/response/headers?header=%s&value=%s",HeaderContentType,MIMEApplicationJSON)NewClient(t).To(ResponseHeadersServer).Get(url).Test().Headers(HeaderContentType,MIMEApplicationJSON)}
HeaderXXX

For more ergonomic development, *htest.Response has many methods to assert all the Headers in const.go

// response_test.gofuncTestResponse_HeaderAccept(t*testing.T) {url:=fmt.Sprintf("/response/headers?header=%s&value=%s",HeaderAccept,"htest")NewClient(t).To(ResponseHeadersServer).Get(url).Test().HeaderAccept("htest")}

Assert Body

You can assert data in body straightly.

// server_test.goMux.Get("/body/user",UserDataHandler)funcUserDataHandler(w http.ResponseWriter,req*http.Request) {io.WriteString(w,UserData)}// response_test.goconst (UserData=`{"id": 1,"name": "hexi"}`)funcTestResponse_Expect(t*testing.T) {NewClient(t).To(Mux).Get("/body/user").Test().StatusOK().Expect(UserData)}

Get Body

You can get data in body straightly

  • String
// response_test.gofuncTestResponse_String(t*testing.T) {assert.Equal(t,UserData,NewClient(t).To(Mux).Get("/body/user").Test().StatusOK().String())}
  • Bytes
// response_test.gofuncTestResponse_Bytes(t*testing.T) {assert.Equal(t, []byte(UserData),NewClient(t).To(Mux).Get("/body/user").Test().StatusOK().Bytes())}

Bind Body

If type of data in body is JSON, you can unmarshal it straightly

// response_test.gotype (Userstruct {IduintNamestring})funcTestResponse_Bind(t*testing.T) {user:=new(User)NewClient(t).To(Mux).Get("/body/user").Test().StatusOK().Bind(user)assert.Equal(t,user.Id,uint(1))assert.Equal(t,user.Name,"hexi")}

Body Types

You can return data in 4 types

As http.Response

As *http.Response is embedded in htest.Response, you can regard *htest.Response as *http.Response. Just like:

assert.Equal(t,"HTTP/1.1",NewClient(t).To(Mux).Get("/body/user").Test().Proto)

Body

htest provide 4 types of data to be returned

JSON

data as JSON

Assert JSON Key
  • Exist(key string)
  • NotExist(key string)
  • String(key, expect string)
  • Int(key string, expect int64)
  • True(key string)
  • False(key string)
  • Uint(key string, expect uint64)
  • Time(key string, expect time.Time)
  • Float(key string, expect float64)
// body_test.gofuncTestJSON_Exist(t*testing.T) {NewClient(t).To(Mux).Get("/name").Test().StatusOK().JSON().Exist("name").NotExist("stuid")}
funcTestJSON_String(t*testing.T) {user:=new(User)NewClient(t).To(Mux).Get("/body/user").Test().StatusOK().JSON().String("name", "hexi)}
Assert JSON Empty or Not
funcTestJSON_NotEmpty(t*testing.T) {user:=new(User)NewClient(t).To(Mux).Get("/body/user").Test().StatusOK().JSON().NotEmpty()}
Bind JSON
// body_test.gotype (Userstruct {IduintNamestring})funcTestJSON_Bind(t*testing.T) {user:=new(User)NewClient(t).To(Mux).Get("/body/user").Test().StatusOK().JSON().Bind(user)assert.Equal(t,user.Id,uint(1))assert.Equal(t,user.Name,"hexi")}

XML

Same as JSON.

For more examples, you can find them in body_test.go

MD5

Assert MD5 Hash
// body_test.gofuncTestMD5_Expect(t*testing.T) {NewClient(t).To(Mux).Get("/body/user").Test().StatusOK().MD5().Expect(UserDataMD5)}
Get MD5 Hash value
hash:=NewClient(t).To(Mux).Get("/body/user").Test().StatusOK().MD5().Body()

SHA1

Same as MD5.

For more examples, you can find them in body_test.go

Appendix

consts

There are many constants of header or header value in const.go

// const.gopackage htest// HTTP methodsconst (CONNECT="CONNECT"DELETE="DELETE"GET="GET"HEAD="HEAD"OPTIONS="OPTIONS"PATCH="PATCH"POST="POST"PUT="PUT"TRACE="TRACE")// MIME typesconst (MIMEApplicationJSON="application/json"MIMEApplicationJSONCharsetUTF8=MIMEApplicationJSON+"; "+charsetUTF8MIMEApplicationJavaScript="application/javascript"MIMEApplicationJavaScriptCharsetUTF8=MIMEApplicationJavaScript+"; "+charsetUTF8MIMEApplicationXML="application/xml"MIMEApplicationXMLCharsetUTF8=MIMEApplicationXML+"; "+charsetUTF8MIMETextXML="text/xml"MIMETextXMLCharsetUTF8=MIMETextXML+"; "+charsetUTF8MIMEApplicationForm="application/x-www-form-urlencoded"MIMEApplicationProtobuf="application/protobuf"MIMEApplicationMsgpack="application/msgpack"MIMETextHTML="text/html"MIMETextHTMLCharsetUTF8=MIMETextHTML+"; "+charsetUTF8MIMETextPlain="text/plain"MIMETextPlainCharsetUTF8=MIMETextPlain+"; "+charsetUTF8MIMEMultipartForm="multipart/form-data"MIMEOctetStream="application/octet-stream")const (charsetUTF8="charset=UTF-8")// Headersconst (HeaderAccept="Accept"HeaderAcceptEncoding="Accept-Encoding"HeaderAllow="Allow"HeaderAuthorization="Authorization"HeaderContentDisposition="Content-Disposition"HeaderContentEncoding="Content-Encoding"HeaderContentLength="Content-Length"HeaderContentType="Content-Type"HeaderCookie="Cookie"HeaderSetCookie="Set-Cookie"HeaderIfModifiedSince="If-Modified-Since"HeaderLastModified="Last-Modified"HeaderLocation="Location"HeaderUpgrade="Upgrade"HeaderVary="Vary"HeaderWWWAuthenticate="WWW-Authenticate"HeaderXForwardedFor="X-Forwarded-For"HeaderXForwardedProto="X-Forwarded-Proto"HeaderXForwardedProtocol="X-Forwarded-Protocol"HeaderXForwardedSsl="X-Forwarded-Ssl"HeaderXUrlScheme="X-Url-Scheme"HeaderXHTTPMethodOverride="X-HTTP-Method-Override"HeaderXRealIP="X-Real-IP"HeaderXRequestID="X-Request-ID"HeaderServer="Server"HeaderOrigin="Origin"// Access controlHeaderAccessControlRequestMethod="Access-Control-Request-Method"HeaderAccessControlRequestHeaders="Access-Control-Request-Headers"HeaderAccessControlAllowOrigin="Access-Control-Allow-Origin"HeaderAccessControlAllowMethods="Access-Control-Allow-Methods"HeaderAccessControlAllowHeaders="Access-Control-Allow-Headers"HeaderAccessControlAllowCredentials="Access-Control-Allow-Credentials"HeaderAccessControlExposeHeaders="Access-Control-Expose-Headers"HeaderAccessControlMaxAge="Access-Control-Max-Age"// SecurityHeaderStrictTransportSecurity="Strict-Transport-Security"HeaderXContentTypeOptions="X-Content-Type-Options"HeaderXXSSProtection="X-XSS-Protection"HeaderXFrameOptions="X-Frame-Options"HeaderContentSecurityPolicy="Content-Security-Policy"HeaderXCSRFToken="X-CSRF-Token")

[8]ページ先頭

©2009-2025 Movatter.jp