当前位置:网站首页>Go language unit test simulates service request and interface return
Go language unit test simulates service request and interface return
2022-06-21 21:48:00 【1024 Q】
Preface
httptest
gock
install
Examples of use
summary
Preface This is a Go Unit testing from getting started to quitting the tutorial series 1 piece , How to use httptest and gock Tools for network testing .
In the last article 《Go Unit testing goes from getting started to giving up —0. Unit test basis 》 in , We introduced Go The basic content of language writing unit test .
However, the business scenarios in actual work are often complex , Whether our code is as server Or do we rely on other people to provide network services ( Call someone else's API Interface ) Scene , We usually don't want to really establish a network connection during the test process . This article specifically introduces how to mock Network testing .
stay Web Unit tests in development scenarios , If it involves HTTP Request recommendation Go Standard library net/http/httptest To test , It can significantly improve the testing efficiency .
In this section , We use the common gin Framework for example , Show me how to http server Write unit tests .
Suppose our business logic is to build a http server End , External provision HTTP service . We wrote a helloHandler function , Used to process user requests .
// gin.gopackage httptest_demoimport ( "fmt" "net/http" "github.com/gin-gonic/gin")// Param Request parameters type Param struct { Name string `json:"name"`}// helloHandler /hello Request handling function func helloHandler(c *gin.Context) { var p Param if err := c.ShouldBindJSON(&p); err != nil { c.JSON(http.StatusOK, gin.H{ "msg": "we need a name", }) return } c.JSON(http.StatusOK, gin.H{ "msg": fmt.Sprintf("hello %s", p.Name), })}// SetupRouter route func SetupRouter() *gin.Engine { router := gin.Default() router.POST("/hello", helloHandler) return router} Now we need to helloHandler Function writing unit test , In this case, we can use httptest This tool mock One HTTP Request and response recorder , Let's have server The client receives and processes us mock Of HTTP request , At the same time, the response recorder is used to record server The response content returned by the client .
The example code of unit test is as follows :
// gin_test.gopackage httptest_demoimport ( "encoding/json" "net/http" "net/http/httptest" "strings" "testing" "github.com/stretchr/testify/assert")func Test_helloHandler(t *testing.T) { // Define two test cases tests := []struct { name string param string expect string }{ {"base case", `{"name": "liwenzhou"}`, "hello liwenzhou"}, {"bad case", "", "we need a name"}, } r := SetupRouter() for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // mock One HTTP request req := httptest.NewRequest( "POST", // Request method "/hello", // request URL strings.NewReader(tt.param), // Request parameters ) // mock A response recorder w := httptest.NewRecorder() // Give Way server End treatment mock Request and record the returned response content r.ServeHTTP(w, req) // Verify whether the status code meets the expectation assert.Equal(t, http.StatusOK, w.Code) // Parse and verify whether the response content is compound with the expectation var resp map[string]string err := json.Unmarshal([]byte(w.Body.String()), &resp) assert.Nil(t, err) assert.Equal(t, tt.expect, resp["msg"]) }) }}Perform unit tests , Check the test results
* go test -v
=== RUN Test_helloHandler
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
[GIN-debug] POST /hello --> golang-unit-test-demo/httptest_demo.helloHandler (3 handlers)
=== RUN Test_helloHandler/base_case
[GIN] 2021/09/14 - 22:00:04 | 200 | 164.839µs | 192.0.2.1 | POST "/hello"
=== RUN Test_helloHandler/bad_case
[GIN] 2021/09/14 - 22:00:04 | 200 | 23.723µs | 192.0.2.1 | POST "/hello"
--- PASS: Test_helloHandler (0.00s)
--- PASS: Test_helloHandler/base_case (0.00s)
--- PASS: Test_helloHandler/bad_case (0.00s)
PASS
ok golang-unit-test-demo/httptest_demo 0.055s
Through this example, we have mastered how to use httptest stay HTTP Server Unit tests are written for the request handling function in the service .
gockThe above example shows how to do this in HTTP Server Write unit tests for request handling functions in the service class scenario , So if we are requesting an external in code API Scene ( Such as through API Call other services to get the return value ) How to write unit tests ?
for example , We have the following business logic code , Rely on the outside API:http://your-api.com/post Data provided .
// api.go// ReqParam API Request parameters type ReqParam struct { X int `json:"x"`}// Result API Return results type Result struct { Value int `json:"value"`}func GetResultByAPI(x, y int) int { p := &ReqParam{X: x} b, _ := json.Marshal(p) // Calling other services API resp, err := http.Post( "http://your-api.com/post", "application/json", bytes.NewBuffer(b), ) if err != nil { return -1 } body, _ := ioutil.ReadAll(resp.Body) var ret Result if err := json.Unmarshal(body, &ret); err != nil { return -1 } // This is right API Do some logic processing on the returned data return ret.Value + y}When writing unit tests for business code like the above , If you don't really want to send requests during the testing process or the dependent external interface has not been developed yet , In unit tests, we can test the dependent API Conduct mock.
It is recommended to use gock This library .
installgo get -u gopkg.in/h2non/gock.v1 Examples of use Use gock To the outside API Conduct mock, namely mock Specify the parameters to return the agreed response content . In the following code mock Two sets of data , Two test cases are composed .
// api_test.gopackage gock_demoimport ( "testing" "github.com/stretchr/testify/assert" "gopkg.in/h2non/gock.v1")func TestGetResultByAPI(t *testing.T) { defer gock.Off() // Refresh pending after test execution mock // mock Ask outside api Shi Chuanshen x=1 return 100 gock.New("http://your-api.com"). Post("/post"). MatchType("json"). JSON(map[string]int{"x": 1}). Reply(200). JSON(map[string]int{"value": 100}) // Call our business function res := GetResultByAPI(1, 1) // Verify whether the returned result meets the expectation assert.Equal(t, res, 101) // mock Ask outside api Shi Chuanshen x=2 return 200 gock.New("http://your-api.com"). Post("/post"). MatchType("json"). JSON(map[string]int{"x": 2}). Reply(200). JSON(map[string]int{"value": 200}) // Call our business function res = GetResultByAPI(2, 2) // Verify whether the returned result meets the expectation assert.Equal(t, res, 202) assert.True(t, gock.IsDone()) // Assertion mock Be triggered }Execute the unit tests written above , Look at the test results .
* go test -v
=== RUN TestGetResultByAPI
--- PASS: TestGetResultByAPI (0.00s)
PASS
ok golang-unit-test-demo/gock_demo 0.054s
The test results are in perfect agreement with the expectations .
In this example , In order to let everyone know clearly gock Use , I deliberately did not use table driven testing . Leave a little homework for everyone : Rewrite this unit test into a table driven test style by yourself , As a review and test of the last two tutorials .
Here the webmaster comes to represent the class , You can send this assignment to me by private mail on the official account , Let's exchange the answers . If you want to fish, you can ask me for the answer directly , But don't go whoring for nothing , There must be a third company :).
summary How to deal with external dependencies when writing unit tests for code in daily work development is the most common problem , This article explains how to use it httptest and gock Tools mock Related dependencies .
Later we will go further , Details on dependencies MySQL and Redis The scenario of how to write unit tests , More about Go For information about unit test simulation service request and interface return, please pay attention to other relevant articles on Sdn !
边栏推荐
- Jerry's near end tone change problem of opening four channel call [chapter]
- China micro semiconductor has passed the registration: the annual revenue is 1.1 billion, and the actual controller is New Zealand nationality
- 15 iterator
- From casual to boring to sick
- prototype扩展:实现对象继承
- How to make file read only when an idea file is locked?
- Data processing and visualization of machine learning [iris data classification | feature attribute comparison]
- 合并两个有序数组
- 英文论文的proposal怎么写?
- Ln2220 2A overcurrent 5v1a High Efficiency Boost IC chip dc/dc voltage regulator
猜你喜欢

Which iPad apps can read English literature well?

你真的了解二叉树吗?(上篇)

天齐锂业通过聆讯:单季净利33亿 蒋卫平夫妇身价超500亿

智力题整理总结

How to use the free and easy-to-use reference management software Zotero? Can I support both Chinese and English
![P6758 [BalticOI2013] Vim](/img/07/b16c8d329b33424e931d9eaedae73a.png)
P6758 [BalticOI2013] Vim

Xr34082a high efficiency boost dc/dc regulator IC

Write your own compiler: intermediate code generation for loop statements such as while, for, and do
![Data processing and visualization of machine learning [iris data classification | feature attribute comparison]](/img/10/6774abdfde345e4133b1986f488874.png)
Data processing and visualization of machine learning [iris data classification | feature attribute comparison]

Revenue and profit "ebb and flow", water drops turn in pain
随机推荐
ACM. Hj35 serpentine matrix ●
In the anchoring stage of retail digitalization, more attention is paid to how to mine and transform traffic by means of Digitalization
Xcode plug-in management tool Alcatraz
杰理之做蓝牙发射时,将立体声修改成单声道差分输出时,接收端出现卡音【篇】
Delaying patient self-help guide | "I have 100 excuses for not delaying, but I am not willing to take a step"
Tkinter drawing component (29) -- Radio Group Control
撰写学术论文引用文献时,标准的格式是怎样的?
合并两个有序数组
Uibutton implements left text and right picture
ARP protocol and ARP attack
PowerPoint tutorial, how to organize slides into groups in PowerPoint?
ACM. HJ51 输出单向链表中倒数第k个结点 ●
CF1481F AB Tree
Ln2220 2A overcurrent 5v1a High Efficiency Boost IC chip dc/dc voltage regulator
J - Count the string HDU - 3336 (KMP)
JS里的数据类型(基础)
China micro semiconductor has passed the registration: the annual revenue is 1.1 billion, and the actual controller is New Zealand nationality
Implementation principle of global load balancing
JS中的构造函数(重点)
杰理之配对成对耳后,想保持两个耳机都输出立体声【篇】