Maison  >  Article  >  développement back-end  >  Créez une date limiteExceededError pour les tests unitaires avec timeout : true

Créez une date limiteExceededError pour les tests unitaires avec timeout : true

WBOY
WBOYavant
2024-02-09 13:00:18670parcourir

Créez une date limiteExceededError pour les tests unitaires avec timeout : true

L'éditeur PHP Xiaoxin est là pour vous présenter une astuce sur les tests unitaires : créez un délai ExceededError : true pour les tests unitaires avec timeout. Lors de l'exécution de tests unitaires, vous pouvez parfois rencontrer un délai d'expiration d'exécution du test. Dans ce cas, nous pouvons résoudre ce problème en définissant delayExceededError sur true. Cette technique peut nous aider à mieux contrôler et gérer le temps d’exécution du test et à garantir l’exactitude et la fiabilité du test. Ensuite, nous présenterons en détail comment utiliser cette technique pour améliorer l'efficacité et la fiabilité des tests unitaires.

Contenu de la question

J'essaie de créer un test unitaire dans mon projet où je me moque d'un client http et définit la réponse que le client doit renvoyer. J'ai besoin de ce comportement car mon code doit se comporter en conséquence au cas où le client http échouerait avec un délai d'attente : je dois donc me moquer du client http pour renvoyer une date limiteExceededError et un test unitaire à partir de celui-ci.

Ce que j'ai essayé jusqu'à présent, c'est de simuler la fonction client do de manière à ce que client.do renvoie :

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

Cela fonctionne, mais pas complètement, ce qui signifie que lorsque j'exécute le code avec ce comportement simulé, le type d'erreur renvoyé est :

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

C'est encore une fois correct, mais pas complètement. Pourquoi? Parce que si j'exécute le code et qu'un véritable timeout se produit, j'obtiens quelque chose de plus complet :

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

Ce qui m'intéresse le plus, c'est timeout: true. Si j'arrive à dire à ma simulation de la renvoyer, je peux l'affirmer, ce que je trouve plus complet que simplement affirmer que l'erreur renvoyée est de type deadlineexceedederror.

Solution

Pour éviter de rendre le test trop complexe, je vous recommande d'adopter cette approche. Tout d'abord, commencez par définir votre erreur :

type timeouterror struct {
    err     string
    timeout bool
}

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

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

De cette façon, timeouterror就同时实现了error()timeoutinterface.
Ensuite, vous devez définir un mock pour le client http :

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

Cela renvoie simplement l'erreur définie ci-dessus et nil comme http.response. Enfin, voyons comment rédiger un exemple de test unitaire :

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

    _, err := client.Do(r)

    fmt.Println(err.Error())
}

Si vous déboguez ce test et faites une pause avec le débogueur sur la variable err, vous verrez les résultats souhaités.
De cette façon, vous pouvez obtenir les fonctionnalités souhaitées sans aucune complexité supplémentaire. Dites-moi si cela marche pour vous!

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer