Golang: HTTP-Antworten mit httptest abfangen und simulieren

王林
Freigeben: 2024-02-09 08:24:33
nach vorne
1135 Leute haben es durchsucht

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
}
Nach dem Login kopieren

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
}
Nach dem Login kopieren

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{})
}
Nach dem Login kopieren

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)
}
Nach dem Login kopieren

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!

Quelle:stackoverflow.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!