Heim  >  Artikel  >  Backend-Entwicklung  >  Wie kann ich „http.Request.FormFile“ in Go zum Testen von Web-Endpunkten verspotten?

Wie kann ich „http.Request.FormFile“ in Go zum Testen von Web-Endpunkten verspotten?

Linda Hamilton
Linda HamiltonOriginal
2024-11-04 04:10:01753Durchsuche

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

Go testen: Request.FormFile verspotten

Beim Testen von Go-Webendpunkten kann es vorkommen, dass man auf die Herausforderung stößt, http zu verspotten. Request.FormFile-Feld. Dieses Feld stellt hochgeladene Dateien innerhalb einer Anfrage dar und ist für das Testen der Endpunktfunktionalität unerlässlich.

Um dieses Problem zu beheben, könnte man erwägen, die gesamte http.Request.FormFile-Struktur zu verspotten. Dies ist jedoch ein unnötiger Schritt. Das Paket mime/multipart bietet einen effizienteren Ansatz.

Das Paket mime/multipart stellt einen Writer-Typ bereit, der eine FormFile-Instanz generieren kann. Wie in der Dokumentation angegeben:

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

Die CreateFormFile-Funktion gibt einen io.Writer zurück, der zum Erstellen eines FormFile-Felds verwendet werden kann. Dieser io.Writer kann dann als Argument an httptest.NewRequest übergeben werden, das einen Leser als Argument akzeptiert.

Um diese Technik zu implementieren, kann man die FormFile entweder in einen io.ReaderWriter-Puffer schreiben oder einen verwenden io.Pipe. Das folgende Beispiel veranschaulicht den letztgenannten Ansatz:

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

Dieses Beispiel bietet einen vollständigen Ablauf zum Testen eines Endpunkts, der Datei-Uploads verarbeitet, von der Generierung einer Schein-FormFile bis zur Bestätigung des Antwortstatuscodes und der Dateierstellung. Durch die Verwendung des Mime/Multipart-Pakets und der Pipes können Sie eine Anfrage, die hochgeladene Dateien enthält, effizient simulieren und Ihre Endpunkte gründlich testen.

Das obige ist der detaillierte Inhalt vonWie kann ich „http.Request.FormFile“ in Go zum Testen von Web-Endpunkten verspotten?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn