Heim  >  Artikel  >  Backend-Entwicklung  >  Unit-Test-HTTP-Anforderungswiederholungen mit httptest

Unit-Test-HTTP-Anforderungswiederholungen mit httptest

WBOY
WBOYnach vorne
2024-02-10 12:30:09716Durchsuche

使用 httptest 单元测试 http 请求重试

Der PHP-Editor Baicao stellt Ihnen ein Unit-Test-Tool namens „httptest“ vor, das Entwicklern beim erneuten Testen von HTTP-Anfragen helfen kann. Dieses Tool kann nicht nur verschiedene HTTP-Anfragen simulieren, sondern auch Anfragen automatisch wiederholen, um die Stabilität und Zuverlässigkeit des Codes sicherzustellen. Mit dem httptest-Tool können Entwickler problemlos HTTP-Anfragen Unit-Tests durchführen und Anfragen als Reaktion auf Netzwerkinstabilität oder andere ungewöhnliche Situationen problemlos wiederholen. Die Verwendung dieses Tools kann die Entwicklungseffizienz erheblich verbessern und die Fehlerwahrscheinlichkeit verringern. Es ist ein Tool, das für jeden PHP-Entwickler einen Versuch wert ist.

Frageninhalt

Ich versuche, Komponententests für eine Komponente namens HttpRequest zu schreiben, die HTTP-Anfragen umschließt und das Unmarshalling von Antworten übernimmt. Kürzlich habe ich dieser Komponente eine Funktion hinzugefügt, die es ihr ermöglicht, HTTP-Anfragen erneut zu versuchen, wenn beim ersten Versuch ein Fehler „Verbindung abgelehnt“ auftritt.

Um die HttpRequest-Komponente zu verwenden, rufe ich sie einmal auf: user, err := HttpRequest[User](config)。 config 参数包含执行请求的所有必要信息,例如 URL、方法、超时、重试次数和请求正文。它还将响应正文解组为指定类型的实例(在本例中为 User)

Das Problem tritt auf, wenn ich versuche, ein Szenario zu testen, in dem die erste Anfrage mit der Fehlermeldung „Verbindung abgelehnt“ fehlschlägt, der zweite Versuch jedoch erfolgreich ist. Der Wiederholungsversuch erfolgt innerhalb der Komponente, daher rufe ich die Komponente nur einmal auf.

Ich fand es schwierig, Komponententests für dieses Szenario zu erstellen, denn damit die Anfrage mit „Verbindung abgelehnt“ fehlschlägt, muss am aufgerufenen Port kein Listener vorhanden sein. Das Problem ist, dass ich bei Verwendung der httptest 时,它总是在创建实例时侦听端口,即使使用 httptest.NewUnstartedServer 也是如此。因此,在创建 httptest-Instanz nie die Fehlermeldung „Verbindung abgelehnt“ in meinem Clientcode erhalte.

Der HttpRequest-Aufruf erfolgt jedoch, bevor die httptest 实例之前,我不知道它将侦听哪个端口。 httptest 总是选择一个随机端口,并且无法以编程方式指定一个端口。这意味着我无法在创建 httptest-Instanz erstellt wird.

Hat jemand eine Idee, wie man dieses Szenario effektiv einem Unit-Test unterziehen kann?

Lösung

newunstartedserver Ganz einfach:

func newunstartedserver(handler http.handler) *server {
    return &server{
        listener: newlocallistener(),
        config:   &http.server{handler: handler},
    }
}

Wenn es das Richtige für Sie ist, selbst einen Port zu wählen, können Sie Folgendes tun:

func mynewunstartedserver(port int, handler http.handler) *httptest.server {
    addr := fmt.sprintf("127.0.0.1:%d", port)
    l, err := net.listen("tcp", addr)
    if err != nil {
        addr = fmt.sprintf("[::1]::%d", port)
        if l, err = net.listen("tcp6", addr); err != nil {
            panic(fmt.sprintf("httptest: failed to listen on a port: %v", err))
        }
    }
    return &httptest.server{
        listener: l,
        config:   &http.server{handler: handler},
    }
}

Der Code zum Erstellen des Listeners wurde von httptest.newlocallistener geändert.

Eine weitere Möglichkeit ist die Umsetzung http.roundtripper 接口并使用此 roundtripper 创建一个 http.client. Hier ist ein Beispiel http/client_test.go, kopiert von net/:

type recordingTransport struct {
    req *Request
}

func (t *recordingTransport) RoundTrip(req *Request) (resp *Response, err error) {
    t.req = req
    return nil, errors.New("dummy impl")
}

func TestGetRequestFormat(t *testing.T) {
    setParallel(t)
    defer afterTest(t)
    tr := &recordingTransport{}
    client := &Client{Transport: tr}
    url := "http://dummy.faketld/"
    client.Get(url) // Note: doesn't hit network
    if tr.req.Method != "GET" {
        t.Errorf("expected method %q; got %q", "GET", tr.req.Method)
    }
    if tr.req.URL.String() != url {
        t.Errorf("expected URL %q; got %q", url, tr.req.URL.String())
    }
    if tr.req.Header == nil {
        t.Errorf("expected non-nil request Header")
    }
}

Das obige ist der detaillierte Inhalt vonUnit-Test-HTTP-Anforderungswiederholungen mit httptest. 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