Maison > développement back-end > Golang > le corps du texte

Golang : interceptez et simulez les réponses HTTP à l'aide de httptest

王林
Libérer: 2024-02-09 08:24:33
avant
1133 Les gens l'ont consulté

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

L'éditeur PHP Zimo vous propose un article sur l'utilisation de httptest pour intercepter et simuler les réponses HTTP dans Golang. Dans cet article, nous examinerons en profondeur comment utiliser le package httptest pour intercepter les requêtes HTTP et simuler les réponses pour les tests unitaires et fonctionnels. En utilisant httptest, nous pouvons facilement simuler des réponses HTTP dans divers scénarios pour tester l'exactitude et la robustesse de notre code. La maîtrise de ces techniques est très utile aussi bien pour les développeurs débutants que confirmés. Découvrons ensuite la méthode de mise en œuvre spécifique !

Contenu de la question

J'ai examiné différents outils disponibles pour des tests simulés dans Golang, mais j'essaie d'utiliser httptest pour accomplir cette tâche. J'ai notamment une fonction comme celle-ci :

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
}
Copier après la connexion

Une grande partie de la documentation que j'ai lue semble nécessiter la création d'une interface client ou d'un transport personnalisé. Existe-t-il un moyen de simuler la réponse dans un fichier de test sans modifier ce code principal ? Je souhaite conserver mon client, sa réponse et tous les détails associés dans l'appel getresponse 函数中。我可能有错误的想法,但我正在尝试找到一种方法来拦截 http.defaultclient.do(req) et renvoyer une réponse personnalisée, est-ce possible ?

Solution de contournement

J'ai lu qu'il semble que vous deviez créer une interface client

Ne changez pas du tout ce code principal

Garder votre code propre est une bonne pratique, vous finirez par vous y habituer, le code testable est plus propre et le code plus propre est plus testable, alors ne vous inquiétez pas de changer votre code (à l'aide d'interfaces) pour qu'il puisse accepter les objets simulés .

La forme de code la plus simple peut ressembler à ceci :

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
}
Copier après la connexion

Votre test pourrait ressembler à ceci :

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{})
}
Copier après la connexion

Mais si vous préférez utiliser httptest :

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)
}
Copier après la connexion

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!

source:stackoverflow.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!