- Notifications
You must be signed in to change notification settings - Fork3
htest is a http-test package
License
Hexilee/htest
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Test a Handler or a 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.)
// 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")}
// 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")}
Send a http request and test the response
// request_test.gofuncTestRequest_Send(t*testing.T) {NewClient(t).Get("https://api.github.com/users/Hexilee").Send().StatusOK().JSON().String("login","Hexilee")}
Set mock server to be tested (Do not need it when you test real server)
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")}
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 htest.Request using different http methods
For example
- Get
// client.gofunc (cClient)Get(pathstring)*Request
More
- Head
- Trace
- Options
- Connect
- Delete
- Post
- Put
- Patch
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 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())}
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()}
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 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()
Assert Response.StatusCode
*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)}
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 Response.Headlers
*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)}
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")}
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)}
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())}
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")}
You can return data in 4 types
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)
htest provide 4 types of data to be returned
data as JSON
- 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)}
funcTestJSON_NotEmpty(t*testing.T) {user:=new(User)NewClient(t).To(Mux).Get("/body/user").Test().StatusOK().JSON().NotEmpty()}
// 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")}
Same as JSON.
For more examples, you can find them in body_test.go
// body_test.gofuncTestMD5_Expect(t*testing.T) {NewClient(t).To(Mux).Get("/body/user").Test().StatusOK().MD5().Expect(UserDataMD5)}
hash:=NewClient(t).To(Mux).Get("/body/user").Test().StatusOK().MD5().Body()
Same as MD5.
For more examples, you can find them in body_test.go
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")
About
htest is a http-test package
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.