Heim  >  Artikel  >  Backend-Entwicklung  >  Erstellen Sie einen DeadlineExceededError für Unit-Tests mit Timeout: true

Erstellen Sie einen DeadlineExceededError für Unit-Tests mit Timeout: true

WBOY
WBOYnach vorne
2024-02-09 13:00:18667Durchsuche

Erstellen Sie einen DeadlineExceededError für Unit-Tests mit Timeout: true

PHP-Editor Xiaoxin ist hier, um Ihnen einen Tipp zum Unit-Testen vorzustellen: Erstellen Sie einen DeadlineExceededError: true für Unit-Tests mit Timeout. Bei der Durchführung von Unit-Tests kann es manchmal zu einer Zeitüberschreitung bei der Testausführung kommen. In diesem Fall können wir dieses Problem lösen, indem wir „deadlineExceededError“ auf „true“ setzen. Diese Technik kann uns helfen, die Testausführungszeit besser zu kontrollieren und zu verwalten und die Genauigkeit und Zuverlässigkeit des Tests sicherzustellen. Als nächstes werden wir detailliert vorstellen, wie diese Technik verwendet werden kann, um die Effizienz und Zuverlässigkeit von Unit-Tests zu verbessern.

Frageninhalt

Ich versuche, in meinem Projekt einen Komponententest zu erstellen, bei dem ich einen http-Client verspotte und die Antwort festlege, die der Client zurückgeben muss. Ich benötige dieses Verhalten, weil sich mein Code entsprechend verhalten muss, falls der http-Client mit einer Zeitüberschreitung ausfällt: Ich muss also den http-Client verspotten, um einen „deadlineExceededError“ zurückzugeben und daraus einen Komponententest durchzuführen.

Was ich bisher versucht habe, ist, die Client-Do-Funktion so zu simulieren, dass client.do Folgendes zurückgibt:

getdofunc = func(*http.request) (*http.response, error) {
    return nil, &url.error{
        op:  "post",
        err: context.deadlineexceeded,
    }
}

Es funktioniert, aber nicht vollständig, was bedeutet, dass wenn ich den Code mit diesem simulierten Verhalten ausführe, der zurückgegebene Fehlertyp ist:

error(*net/url.error) *{op: "post", url: "", err: error(context.deadlineexceedederror) {}}

Das ist wieder richtig, aber nicht vollständig. Warum? Denn wenn ich den Code ausführe und es zu einer echten Zeitüberschreitung kommt, erhalte ich etwas Vollständigeres:

error(*net/url.Error) *{Op: "Post", URL: "http://localhost:4500/scan/", Err: error(*net/http.httpError) *{err: "context deadline exceeded (Client.Timeout exceeded while awaiting headers)", timeout: true}}

Was mich am meisten interessiert, ist timeout: true. Wenn es mir gelingt, meinem Mock mitzuteilen, dass er es zurückgeben soll, kann ich dies behaupten, was meiner Meinung nach vollständiger ist, als nur zu behaupten, dass der zurückgegebene Fehler vom Typ deadlineexceedederror ist.

Lösung

Um zu komplexe Tests zu vermeiden, empfehle ich Ihnen, diesen Ansatz zu übernehmen. Beginnen Sie zunächst damit, Ihren Fehler zu definieren:

type timeouterror struct {
    err     string
    timeout bool
}

func (e *timeouterror) error() string {
    return e.err
}

func (e *timeouterror) timeout() bool {
    return e.timeout
}

Auf diese Weise, timeouterror就同时实现了error()timeoutSchnittstelle.
Dann müssen Sie Mock für den http-Client definieren:

type mockclient struct{}

func (m *mockclient) do(req *http.request) (*http.response, error) {
    return nil, &timeouterror{
        err:     "context deadline exceeded (client.timeout exceeded while awaiting headers)",
        timeout: true,
    }
}

Dies gibt lediglich den oben definierten Fehler zurück und nil als http.response. Schauen wir uns zum Schluss an, wie man einen Beispiel-Unit-Test schreibt:

func TestSlowServer(t *testing.T) {
    r := httptest.NewRequest(http.MethodGet, "http://example.com", nil)
    client := &mockClient{}

    _, err := client.Do(r)

    fmt.Println(err.Error())
}

Wenn Sie diesen Test debuggen und mit dem Debugger für die err-Variable pausieren, werden die gewünschten Ergebnisse angezeigt.
Auf diese Weise können Sie die gewünschte Funktionalität ohne zusätzliche Komplexität erreichen. Lassen Sie mich wissen, ob es für Sie funktioniert!

Das obige ist der detaillierte Inhalt vonErstellen Sie einen DeadlineExceededError für Unit-Tests mit Timeout: true. 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