The httptest package provides utilities for HTTP testing:
Test server handler logic by mocking the request.
Test client logic by mocking the server handler.
For server handler testing, you need ResponseRecorder object to record the
http.ResponseWriter’s mutations, plus httptest.NewRequest and pass them into
the server handler for (w http.ResponseWriter, r *http.Request).
For client logic testing, you need to mock specific server handler or
even entire server, using the httptest.NewServer Object or other server types.
For client logic testing, if you only set up one handler and call it repeatedly,
it returns the same response. If you do want to have different response when you
call mock server, here is the
example,
I enrich it by adding more in handlers.
funcmain() { responseCounter := 0 responses := []func(w http.ResponseWriter, r *http.Request){ // Transfer into upper case for word provided // Hand GET request func(w http.ResponseWriter, r *http.Request) { query, err := url.ParseQuery(r.URL.RawQuery) if err != nil { w.WriteHeader(http.StatusBadRequest) fmt.Fprintf(w, "invalid request") return } word := query.Get("word") iflen(word) == 0 { w.WriteHeader(http.StatusBadRequest) fmt.Fprintf(w, "missing word") return } w.WriteHeader(http.StatusOK) fmt.Fprintf(w, strings.ToUpper(word)) }, // Handle POST request to get message func(w http.ResponseWriter, r *http.Request) { if r.Method == http.MethodPost { body, err := ioutil.ReadAll(r.Body) if err != nil { fmt.Println(err) return } // Parse the request body as JSON. var data struct { Name string`json:"name"` Email string`json:"email"` } err = json.Unmarshal(body, &data) if err != nil { fmt.Println(err) return } // Print the name and email of the user who submitted the form. fmt.Println("Name:", data.Name) fmt.Println("Email:", data.Email) fmt.Println("Header:", r.Header) } }, } ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { responses[responseCounter](w, r) responseCounter++ // Using counter to rotate if you have many more calls responseCounter = responseCounter % 2 })) defer ts.Close()
// call from client with different http method clientGetMethod(ts.URL + "?word=school") // bad call, will get your error message clientGetMethod(ts.URL + "?apple") clientPostMethod(ts.URL) }