Golang: Intercept and simulate HTTP responses using httptest

王林
Release: 2024-02-09 08:24:33
forward
1160 people have browsed it

Golang:使用 httptest 拦截和模拟 HTTP 响应

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!

Question content

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
}
Copy after login

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?

Solution

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
}
Copy after login

Your test could look like this:

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{})
}
Copy after login

But if you prefer to use httptest:

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)
}
Copy after login

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!

source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template