This is a creation in
Article, where the information may have evolved or changed.
After we developed a Web server with go, we intend to unit test write the handler function, before you know httptest, use a rather stupid method
is to compile and run the Web server, then use go to write a client program to the Web server corresponding to the route to send data and then resolve
The returned data. This method is very cumbersome to test, it is very simple to use httptest to test, can be used with the testing test.
Httptest Basic Use Method
Suppose handler is already written in the server.
http.HandleFunc("/health-check", HealthCheckHandler)func HealthCheckHandler(w http.ResponseWriter, r *http.Request) { // A very simple health check. w.WriteHeader(http.StatusOK) w.Header().Set("Content-Type", "application/json") // In the future we could report back on the status of our DB, or our cache // (e.g. Redis) by performing a simple PING, and include them in the response. io.WriteString(w, `{"alive": true}`)}
The test is as follows:
import ( "net/http" "net/http/httptest" "testing")func TestHealthCheckHandler(t *testing.T) { //创建一个请求 req, err := http.NewRequest("GET", "/health-check", nil) if err != nil { t.Fatal(err) } // 我们创建一个 ResponseRecorder (which satisfies http.ResponseWriter)来记录响应 rr := httptest.NewRecorder() //直接使用HealthCheckHandler,传入参数rr,req HealthCheckHandler(rr, req) // 检测返回的状态码 if status := rr.Code; status != http.StatusOK { t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusOK) } // 检测返回的数据 expected := `{"alive": true}` if rr.Body.String() != expected { t.Errorf("handler returned unexpected body: got %v want %v", rr.Body.String(), expected) }}
You can then use Run test to perform the tests.
If Web server has the behavior of an operational database, you need to make a connection to the database in the INIT function.
Refer to another test code written in the sample in the official documentation:
func TestHealthCheckHandler2(t *testing.T) { reqData := struct { Info string `json:"info"` }{Info: "P123451"} reqBody, _ := json.Marshal(reqData) fmt.Println("input:", string(reqBody)) req := httptest.NewRequest( http.MethodPost, "/health-check", bytes.NewReader(reqBody), ) req.Header.Set("userid", "wdt") req.Header.Set("commpay", "brk") rr := httptest.NewRecorder() HealthCheckHandler(rr, req) result := rr.Result() body, _ := ioutil.ReadAll(result.Body) fmt.Println(string(body)) if result.StatusCode != http.StatusOK { t.Errorf("expected status 200,",result.StatusCode) }}
Pay attention to different places
- http. Newrequest is replaced with Httptest.newrequest.
- Httptest. The third parameter of the newrequest can be used to pass the body data and must implement IO. Reader interface.
- Httptest. Newrequest does not return error and does not require a err!=nil check.
- Instead of using Responserecorder directly when parsing the response, the result function was called.
Reference
Httptest Doc
Testing Your (HTTP) handlers in Go