php editor Zimo brings you an article about using httptest to intercept and simulate HTTP responses in Golang. In this article, we will take a deep dive into how to use the httptest package to intercept HTTP requests and simulate responses for unit testing and functional testing. By using httptest, we can easily simulate HTTP responses in various scenarios to test the correctness and robustness of our code. Mastering these techniques is very useful for both beginners and experienced developers. Next, let’s learn about the specific implementation method!
I've looked into various different tools available for mock testing in golang, but I'm trying to use httptest to accomplish this task. In particular, I have a function like this:
type contact struct { username string number int } func getResponse(c contact) string { url := fmt.Sprintf("https://mywebsite/%s", c.username) req, err := http.NewRequest(http.MethodGet, url, nil) // error checking resp, err := http.DefaultClient.Do(req) // error checking return response }
A lot of the documentation I've read seems to require creating a client interface or a custom transport. Is there a way to simulate the response in a test file without changing this main code? I want to keep my client, response and all related details in the getresponse
function. I may have the wrong idea but I'm trying to find a way to intercept the http.defaultclient.do(req)
call and return a custom response, is this possible?
I have read that it seems that a client interface needs to be created
Do not change this main code at all
Keeping your code clean is a good practice, you will eventually get used to it, testable code is cleaner, and cleaner code is more testable, so don't worry about changing your code (using interfaces) so that it can Accepts a mock object.
The simplest form of code can be like this:
package main import ( "fmt" "net/http" ) type contact struct { username string number int } type client interface { do(req *http.request) (*http.response, error) } func main() { getresponse(http.defaultclient, contact{}) } func getresponse(client client, c contact) string { url := fmt.sprintf("https://mywebsite/%s", c.username) req, _ := http.newrequest(http.methodget, url, nil) // error checking resp, _ := http.defaultclient.do(req) // error checking and response processing return response }
package main import ( "net/http" "testing" ) type mockclient struct { } // do function will cause mockclient to implement the client interface func (tc mockclient) do(req *http.request) (*http.response, error) { return &http.response{}, nil } func testgetresponse(t *testing.t) { client := new(mockclient) getresponse(client, contact{}) }
package main import ( "fmt" "io" "net/http" "net/http/httptest" ) type contact struct { username string number int } func main() { fmt.Println(getResponse(contact{})) } func getResponse(c contact) string { // Make a test server ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "your response") })) defer ts.Close() // You should still set your base url base_url := ts.URL url := fmt.Sprintf("%s/%s", base_url, c.username) req, _ := http.NewRequest(http.MethodGet, url, nil) // Use ts.Client() instead of http.DefaultClient in your tests. resp, _ := ts.Client().Do(req) // Processing the response response, _ := io.ReadAll(resp.Body) resp.Body.Close() return string(response) }
The above is the detailed content of Golang: Intercept and simulate HTTP responses using httptest. For more information, please follow other related articles on the PHP Chinese website!