Unit testing based on Golang gin framework

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

After writing a Web server with the gin framework, if we need to test the handlers interface function, there are two main ways to do it.

The first is to deploy Web server and then manually impersonate a real HTTP request through a browser or other HTTP request emulation tool, and after sending an HTTP request, parsing the returned response to see if the response is expected, which is cumbersome and the test results are unreliable.

The second is to implement unit tests for handlers interface functions using httptest combined with testing.

Here are some of the ways to share unit tests based on gin with the corresponding unit tests for four interfaces:

Interface Name

Request Address

Request type

Response data type

Response data

Ongetstringrequest

/getstring

Get

String

Success

Onpracticerequest

/practice

Get

HTML page

Practice.html

Onloginrequestforform

/loginform

Post

Json

Onloginrequestforjson

/loginjson

Post

Json

One, sample interface code:

ongetstringrequest :

//Ongetstringrequest return interface for Success strings  ongetstringrequest (c *gin. Context) {c.string (http.  Statusok"Success")}

onpracticerequest :

//Onpracticerequest return practice.html interface of the page  onpracticerequest (c *gin. Context) {c.html (http.  Statusok,"practice.html", gin. h{})}

Onloginrequestforform :

//Onloginrequestforform login interface to pass parameters as a formfuncOnloginrequestforform (c *gin. Context) {req: = &user{}ifERR: = C.shouldbindwith (req, binding. Form); Err! = Nil {log. Printf ("Err:%v", err) C.json (http.Statusok, Gin. h{"errno":"1","ErrMsg":"parameters do not match","Data":"",              })return} C.json (http.Statusok, Gin. h{"errno":"0","ErrMsg":"","Data": Req,})}

Onloginrequestforjson :

//Onloginrequestforjson tothe login interface for passing parameters in JSON formfuncOnloginrequestforjson (c *gin. Context) {req: = &user{}ifERR: = C.shouldbindwith (req, binding. JSON); Err! = Nil {log. Printf ("Err:%v", err) C.json (http.Statusok, Gin. h{"errno":"1","ErrMsg":"parameters do not match","Data":"",              })return} C.json (http.Statusok, Gin. h{"errno":"0","ErrMsg":"","Data": Req,})}

Second, some of the structure and tool functions called:

User struct Code:

//To undertake the front-end transmission over JSON data or Form form Data   ' form: ' Age ' json: ' Age ' binding: ' Required   '}

Loginresponse struct Code:

Response   parameters  ' JSON: ' Data ' 'loginresponse login interface 

Call the tool function:

//PARSETOSTR will The key value pairs in the map are output as QueryString Form   mapvalues}

Three, unit test writing steps:

1. Initialize the route

func init () {
// Initializing routes
router = gin. Default ()
Router. GET ("/getstring", Ongetstringrequest)
Router. POST ("/loginform", Onloginrequestforform)
Router. POST ("/loginjson", Onloginrequestforjson)
Router. Loadhtmlglob ("e:/mygo/resources/pages/*") // define template file path
router. GET ("/practice", Onpracticerequest)
}

When an interface involves operations related to a database, the database service can be added as middleware to the gin context as shown in:

2. Wrapping the function that constructs the HTTP request (so that the test function calls directly to initiate different kinds of HTTP requests)

2.1 Constructing a GET request

//Get based on a specific request URI, initiating GET request Returns response  //Construction  req: = httptest. Newrequest ("GET"//Call the    corresponding// read response  Body,_: = Ioutil. ReadAll (result. Body)  Body}

2.2 Constructing a POST request, passing parameters as a form

//Postform based on a specific requestURI and Parametersparam, passing parameters in form form, initiatingPOST request return responsefuncPostform (URI string, paramMap[String]string, Router *gin. Engine) []byte {//ConstructionPOST request, form data tothe form of QueryString is added toafter the URIReq: = Httptest. Newrequest ("POST", Uri+parsetostr (param), nil)//Initialize responseW: = Httptest. Newrecorder ()//Call the appropriateHandler InterfaceRouter. Servehttp (W, req)//Extract ResponseResult: = W.result ()deferResult. Body.close ()//Read responseBodyBody, _: = Ioutil. ReadAll (result. Body)returnBody

2.3 Constructing a POST request, passing parameters in JSON form

//Postjson based on a specific requestURI and Parametersparam, topass parameters in JSON form, initiatingPOST request return responsefuncPostjson (URI string, paramMap[String]Interface{}, Router *gin. Engine) []byte {//Convert parameters toJSON bit streamJsonbyte,_: = json. Marshal (param)//ConstructionPOST request,JSON data to requestthe form of the body passesReq: = Httptest. Newrequest ("POST", Uri, Bytes. Newreader (Jsonbyte))//Initialize responseW: = Httptest. Newrecorder ()//Call the appropriateHandler InterfaceRouter. Servehttp (W, req)//Extract ResponseResult: = W.result ()deferResult. Body.close ()//Read responseBodyBody,_: = Ioutil. ReadAll (result. Body)returnBody

3. Writing test functions

3.1 Test functions for the Ongetstringrequest interface

//Testongetstringrequest test to gets the interface of a string to get the way   //Initiator Body: = Get (URI, Router) fmt.    Printf ("response:%v\n"{T.errorf ("response string does not match,body:%v\n" ,string (Body))}}

3.2 Test functions for the Onpracticerequest interface

//Testonpracticerequest test toGet method Getpractice.html interface of the pagefuncTestonpracticerequest (t *testing. T) {//Initialize request addressURI: ="/practice"//InitiatingGET RequestBody: = Get (URI, router) fmt. Printf ("response:%v\n", string (body))//Determine if the response is consistent with expectationsHtml,_: = Ioutil. ReadFile ("E:/mygo/resources/pages/practice.html") Htmlstr: = string (HTML)ifHtmlstr! = String (body) {T.errorf ("response data does not match,body:%v\n ", string (Body)}}

3.3 Test functions for the Onloginrequestforform interface

//Testonloginrequestforform Test Login interface to pass parameters in form formfuncTestonloginrequestforform (t *testing. T) {//Initialize request address and request parametersURI: ="/loginform"Param: = Make (Map[String]string] param["username"] ="Valiben"param["Password"] ="123"param["Age"] ="1"//InitiatingPOST request, passing parameters as a formBody: = Postform (URI, param, router) fmt. Printf ("response:%v\n", string (body))//Parse response to determine if the response is consistent with expectationsResponse: = &loginresponse{}ifERR: = json. Unmarshal (body, response); Err! = Nil {T.errorf ("Parse response error,err:%v\n ", err)}offResponse. Data.username! ="Valiben"{T.errorf ("response data does not match,username:%v\n ", Response. Data.username)}}

3.4 Test functions for the Onloginrequestforjson interface

//Testonloginrequestforjson test tothe login interface for passing parameters in JSON formfuncTestonloginrequestforjson (t *testing. T) {//Initialize request address and request parametersURI: ="/loginjson"Param: = Make (Map[String]Interface{}) param["username"] ="Valiben"param["Password"] ="123"param["Age"] = 1//InitiatingThe POST request topassing parameters in JSON formBody: = Postjson (URI, param, router) fmt. Printf ("response:%v\n", string (body))//Parse response to determine if the response is consistent with expectationsResponse: = &loginresponse{}ifERR: = json. Unmarshal (body, response); Err! = Nil {T.errorf ("Parse response error,err:%v\n ", err)}ifResponse. Data.username! ="Valiben"{T.errorf ("response data does not match,username:%v\n ", Response. Data.username)}}

4. Run unit tests to view test results

Execute go test./Run testing code, test results are as follows

Iv. Summary

The main step of unit testing based on gin is to initialize the route first, set the HTTP request address that the handler interface function intercepts (no listener port number), and then through the "Net/http/httptest" Packet Newrequest (method, Target string, body IO. Reader) method constructs the request, the first parameter is the requested type "POST" "GET", and the second parameter is the requested URI address (the parameters of form form can be passed in the form of QueryString appended to the URI address), The third parameter is the request Request body content (JSON data and other types of data can be added here), and then through the Newrecorder () function constructs the response, called the Func (engine *engine) servehttp (w http. Responsewriter, req *http. Request) method to invoke the interface handlers, the returned response will be written to the previously constructed response, and the interface can be tested by parsing the response and viewing the data

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.