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!