Maison  >  Article  >  développement back-end  >  Comment puis-je me moquer de « http.Request.FormFile » dans Go pour tester les points de terminaison Web ?

Comment puis-je me moquer de « http.Request.FormFile » dans Go pour tester les points de terminaison Web ?

Linda Hamilton
Linda Hamiltonoriginal
2024-11-04 04:10:01753parcourir

How can I mock `http.Request.FormFile` in Go for testing web endpoints?

Test de Go : Mocking Request.FormFile

Dans le processus de test des points de terminaison Web Go, on peut rencontrer le défi de se moquer du http. Champ Request.FormFile. Ce champ représente les fichiers téléchargés dans une requête et est essentiel pour tester la fonctionnalité du point de terminaison.

Pour résoudre ce problème, on pourrait envisager de se moquer de l'intégralité de la structure http.Request.FormFile. Cependant, c’est une étape inutile. Le package mime/multipart offre une approche plus efficace.

Le package mime/multipart fournit un type Writer qui peut générer une instance FormFile. Comme indiqué dans la documentation :

CreateFormFile is a convenience wrapper around CreatePart. It creates
a new form-data header with the provided field name and file name.

La fonction CreateFormFile renvoie un io.Writer qui peut être utilisé pour construire un champ FormFile. Ce io.Writer peut ensuite être passé en argument à httptest.NewRequest, qui accepte un lecteur comme argument.

Pour implémenter cette technique, on peut soit écrire le FormFile dans un tampon io.ReaderWriter, soit utiliser un io.Tuyau. L'exemple suivant illustre cette dernière approche :

<code class="go">import (
    "fmt"
    "io"
    "io/ioutil"
    "net/http"
    "net/http/httptest"

    "github.com/codegangsta/multipart"
)

func TestUploadFile(t *testing.T) {
    // Create a pipe to avoid buffering
    pr, pw := io.Pipe()
    // Create a multipart writer to transform data into multipart form data
    writer := multipart.NewWriter(pw)

    go func() {
        defer writer.Close()
        // Create the form data field 'fileupload' with a file name
        part, err := writer.CreateFormFile("fileupload", "someimg.png")
        if err != nil {
            t.Errorf("failed to create FormFile: %v", err)
        }

        // Generate an image dynamically and encode it to the multipart writer
        img := createImage()
        err = png.Encode(part, img)
        if err != nil {
            t.Errorf("failed to encode image: %v", err)
        }
    }()

    // Create an HTTP request using the multipart writer and set the Content-Type header
    request := httptest.NewRequest("POST", "/", pr)
    request.Header.Add("Content-Type", writer.FormDataContentType())

    // Create a response recorder to capture the response
    response := httptest.NewRecorder()

    // Define the handler function to test
    handler := func(w http.ResponseWriter, r *http.Request) {
        // Parse the multipart form data
        if err := r.ParseMultipartForm(32 << 20); err != nil {
            http.Error(w, "failed to parse multipart form data", http.StatusBadRequest)
            return
        }

        // Read the uploaded file
        file, header, err := r.FormFile("fileupload")
        if err != nil {
            if err == http.ErrMissingFile {
                http.Error(w, "missing file", http.StatusBadRequest)
                return
            }
            http.Error(w, fmt.Sprintf("failed to read file: %v", err), http.StatusInternalServerError)
            return
        }
        defer file.Close()

        // Save the file to disk
        outFile, err := os.Create("./uploads/" + header.Filename)
        if err != nil {
            http.Error(w, fmt.Sprintf("failed to save file: %v", err), http.StatusInternalServerError)
            return
        }
        defer outFile.Close()

        if _, err := io.Copy(outFile, file); err != nil {
            http.Error(w, fmt.Sprintf("failed to copy file: %v", err), http.StatusInternalServerError)
            return
        }

        w.Write([]byte("ok"))
    }

    // Serve the request with the handler function
    handler.ServeHTTP(response, request)

    // Verify the response status code and file creation
    if response.Code != http.StatusOK {
        t.Errorf("incorrect HTTP status: %d", response.Code)
    }

    if _, err := os.Stat("./uploads/someimg.png"); os.IsNotExist(err) {
        t.Errorf("failed to create file: ./uploads/someimg.png")
    } else if body, err := ioutil.ReadAll(response.Body); err != nil {
        t.Errorf("failed to read response body: %v", err)
    } else if string(body) != "ok" {
        t.Errorf("incorrect response body: %s", body)
    }
}</code>

Cet exemple fournit un flux complet pour tester un point de terminaison qui gère les téléchargements de fichiers, de la génération d'un FormFile fictif à l'affirmation du code d'état de la réponse et à la création du fichier. En utilisant le package et les canaux MIME/Multipart, vous pouvez simuler efficacement une requête contenant des fichiers téléchargés et tester minutieusement vos points de terminaison.

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