Heim  >  Artikel  >  Backend-Entwicklung  >  Golang: HTTP-Antworten mit httptest abfangen und simulieren

Golang: HTTP-Antworten mit httptest abfangen und simulieren

王林
王林nach vorne
2024-02-09 08:24:331132Durchsuche

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

Der PHP-Editor Zimo bringt Ihnen einen Artikel über die Verwendung von httptest zum Abfangen und Simulieren von HTTP-Antworten in Golang. In diesem Artikel werden wir uns eingehend mit der Verwendung des httptest-Pakets befassen, um HTTP-Anfragen abzufangen und Antworten für Unit-Tests und Funktionstests zu simulieren. Mithilfe von httptest können wir HTTP-Antworten in verschiedenen Szenarien problemlos simulieren, um die Korrektheit und Robustheit unseres Codes zu testen. Die Beherrschung dieser Techniken ist sowohl für Anfänger als auch für erfahrene Entwickler sehr nützlich. Als nächstes lernen wir die spezifische Implementierungsmethode kennen!

Frageninhalt

Ich habe mir verschiedene Tools angesehen, die für Mock-Tests in Golang verfügbar sind, aber ich versuche, httptest zu verwenden, um diese Aufgabe zu erfüllen. Insbesondere habe ich eine Funktion wie diese:

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
}

Ein Großteil der Dokumentation, die ich gelesen habe, erfordert anscheinend die Erstellung einer Client-Schnittstelle oder eines benutzerdefinierten Transports. Gibt es eine Möglichkeit, die Antwort in einer Testdatei zu simulieren, ohne diesen Hauptcode zu ändern? Ich möchte meinen Kunden, meine Antwort und alle zugehörigen Details im getresponse 函数中。我可能有错误的想法,但我正在尝试找到一种方法来拦截 http.defaultclient.do(req) ​​Anruf behalten und eine benutzerdefinierte Antwort zurücksenden. Ist das möglich?

Workaround

Ich habe gelesen, dass es so aussieht, als müssten Sie eine Client-Schnittstelle erstellen

Ändern Sie diesen Hauptcode überhaupt nicht

Es ist eine gute Vorgehensweise, Ihren Code sauber zu halten. Mit der Zeit werden Sie sich daran gewöhnen. Testbarer Code ist sauberer und sauberer Code ist besser testbar. Machen Sie sich also keine Sorgen, Ihren Code (unter Verwendung von Schnittstellen) so zu ändern, dass er Mock-Objekte akzeptieren kann .

Die einfachste Form von Code kann so aussehen:

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
}

Dein Test könnte so aussehen:

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{})
}

Aber wenn Sie lieber httptest verwenden möchten:

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)
}

Das obige ist der detaillierte Inhalt vonGolang: HTTP-Antworten mit httptest abfangen und simulieren. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen