dousong3760 2018-10-25 15:45
浏览 487

想要在单元测试Golang中添加FormFile

I want to test a httpRequest with a json body and a test file. I don't know how to add the created test file to the request beside body json.

body := strings.NewReader(URLTest.RequestBody)
        request, err := http.NewRequest(URLTest.MethodType, "localhost:"+string(listeningPort)+URLTest.URL, body)
        if err != nil {
            t.Fatalf("HTTP NOT WORKING")
        }

        fileBuffer := new(bytes.Buffer)
        mpWriter := multipart.NewWriter(fileBuffer)
        fileWriter, err := mpWriter.CreateFormFile("file", "testfile.pdf")
        if err != nil {
            t.Fatalf(err.Error())
        }
        file, err := os.Open("testfile.pdf")
        if err != nil {
            t.Fatalf(err.Error())
        }
        defer file.Close()
        _, err = io.Copy(fileWriter, file)
        if err != nil {
            t.Fatalf(err.Error())
        }

        rec := httptest.NewRecorder()
        UploadFiles(rec, request, nil)
        response := rec.Result()
        if response.StatusCode != URLTest.ExpectedStatusCode {
            t.Errorf(URLTest.URL + " status mismatch")
        }

        responseBody, err := ioutil.ReadAll(response.Body)
        defer response.Body.Close()

        if err != nil {
            t.Errorf(URLTest.URL + " cant read response")
        } else {
            if strings.TrimSpace(string(responseBody)) != URLTest.ExpectedResponseBody {
                t.Errorf(URLTest.URL + " response mismatch - have: " + string(responseBody) + " want: " + URLTest.ExpectedResponseBody)
            }
        }
    }

Can I add file as a value like request.FormFile.Add(...) or something?

  • 写回答

1条回答 默认 最新

  • doujiao1984 2018-10-25 18:22
    关注

    Regarding your question about how to send a file in an HTTP request with Go, here's some sample code.

    And you will need the mime/multipart package to build the form.

    package main
    
    import (
        "bytes"
        "fmt"
        "io"
        "mime/multipart"
        "net/http"
        "net/http/httptest"
        "net/http/httputil"
        "os"
        "strings"
    )
    
    func main() {
    
        var client *http.Client
        var remoteURL string
        {
            //setup a mocked http client.
            ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
                b, err := httputil.DumpRequest(r, true)
                if err != nil {
                    panic(err)
                }
                fmt.Printf("%s", b)
            }))
            defer ts.Close()
            client = ts.Client()
            remoteURL = ts.URL
        }
    
        //prepare the reader instances to encode
        values := map[string]io.Reader{
            "file":  mustOpen("main.go"), // lets assume its this file
            "other": strings.NewReader("hello world!"),
        }
        err := Upload(client, remoteURL, values)
        if err != nil {
            panic(err)
        }
    }
    
    func Upload(client *http.Client, url string, values map[string]io.Reader) (err error) {
        // Prepare a form that you will submit to that URL.
        var b bytes.Buffer
        w := multipart.NewWriter(&b)
        for key, r := range values {
            var fw io.Writer
            if x, ok := r.(io.Closer); ok {
                defer x.Close()
            }
            // Add an image file
            if x, ok := r.(*os.File); ok {
                if fw, err = w.CreateFormFile(key, x.Name()); err != nil {
                    return
                }
            } else {
                // Add other fields
                if fw, err = w.CreateFormField(key); err != nil {
                    return
                }
            }
            if _, err = io.Copy(fw, r); err != nil {
                return err
            }
    
        }
        // Don't forget to close the multipart writer.
        // If you don't close it, your request will be missing the terminating boundary.
        w.Close()
    
        // Now that you have a form, you can submit it to your handler.
        req, err := http.NewRequest("POST", url, &b)
        if err != nil {
            return
        }
        // Don't forget to set the content type, this will contain the boundary.
        req.Header.Set("Content-Type", w.FormDataContentType())
    
        // Submit the request
        res, err := client.Do(req)
        if err != nil {
            return
        }
    
        // Check the response
        if res.StatusCode != http.StatusOK {
            err = fmt.Errorf("bad status: %s", res.Status)
        }
        return
    }
    

    Hope you can use this in your unit test

    评论

报告相同问题?

悬赏问题

  • ¥15 R语言Rstudio突然无法启动
  • ¥15 关于#matlab#的问题:提取2个图像的变量作为另外一个图像像元的移动量,计算新的位置创建新的图像并提取第二个图像的变量到新的图像
  • ¥15 改算法,照着压缩包里边,参考其他代码封装的格式 写到main函数里
  • ¥15 用windows做服务的同志有吗
  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值