在 Echo 框架中测试多部分表单上传端点
Testing a multipart form upload endpoint in Echo framework
我正在使用 labstack 的 Echo framework 在 Golang 中构建 API。现在我有一个问题,当我想测试一个端点时,我似乎无法绕过。
我有一个这样的处理函数
func DoStuff(c echo.Context) error {
businessUnit := strings.ToUpper(c.FormValue("bu"))
week := c.FormValue("wk")
file, _ := c.FormFile("file")
...
}
处理程序工作正常。我现在遇到的问题是为此编写集成测试。
此端点接受 Content-Type: multipart/form-data
。
这是我的一些其他处理程序测试的样子:
func TestDoStuff(t *testing.T) {
// Not sure about this part tho
body := new(bytes.Buffer)
writer := multipart.NewWriter(body)
writer.WriteField("bu", "HFL")
writer.WriteField("wk", "10")
part, _ := writer.CreateFormFile("file", "file.csv")
part.Write([]byte(`sample`))
e := echo.New()
req := httptest.NewRequest(http.MethodPost, "/endpoint", body)
req.Header.Add("Content-Type", "multipart/form-data")
rec := httptest.NewRecorder()
c := e.NewContext(req, rec)
if assert.NotPanics(t, func(){ _ = DoStuff(c)}){
assert.Equal(t, http.StatusOK, rec.Code)
... more assertions ...
}
}
我似乎无法在处理程序中获取表单值。任何帮助将不胜感激。
TLDR
func TestDoStuff(t *testing.T) {
body := new(bytes.Buffer)
writer := multipart.NewWriter(body)
writer.WriteField("bu", "HFL")
writer.WriteField("wk", "10")
part, _ := writer.CreateFormFile("file", "file.csv")
part.Write([]byte(`sample`))
writer.Close() // <<< important part
e := echo.New()
req := httptest.NewRequest(http.MethodPost, "/endpoint", body)
req.Header.Set("Content-Type", writer.FormDataContentType()) // <<< important part
rec := httptest.NewRecorder()
c := e.NewContext(req, rec)
...
}
说明。
当您关闭 multipart.Writer 时,实际上会将边界 ID 写入 body(这是非常重要的部分!)。该 id 稍后使用 writer.FormDataContentType().
写入 headers
事情是当你调用 FormValue、FormFile 等时调用 req.ParseMultipartForm(),后者又去寻找 multipart/form-data header 中的边界 ID,然后使用said id 搜索 body 数据。
我正在使用 labstack 的 Echo framework 在 Golang 中构建 API。现在我有一个问题,当我想测试一个端点时,我似乎无法绕过。
我有一个这样的处理函数
func DoStuff(c echo.Context) error {
businessUnit := strings.ToUpper(c.FormValue("bu"))
week := c.FormValue("wk")
file, _ := c.FormFile("file")
...
}
处理程序工作正常。我现在遇到的问题是为此编写集成测试。
此端点接受 Content-Type: multipart/form-data
。
这是我的一些其他处理程序测试的样子:
func TestDoStuff(t *testing.T) {
// Not sure about this part tho
body := new(bytes.Buffer)
writer := multipart.NewWriter(body)
writer.WriteField("bu", "HFL")
writer.WriteField("wk", "10")
part, _ := writer.CreateFormFile("file", "file.csv")
part.Write([]byte(`sample`))
e := echo.New()
req := httptest.NewRequest(http.MethodPost, "/endpoint", body)
req.Header.Add("Content-Type", "multipart/form-data")
rec := httptest.NewRecorder()
c := e.NewContext(req, rec)
if assert.NotPanics(t, func(){ _ = DoStuff(c)}){
assert.Equal(t, http.StatusOK, rec.Code)
... more assertions ...
}
}
我似乎无法在处理程序中获取表单值。任何帮助将不胜感激。
TLDR
func TestDoStuff(t *testing.T) {
body := new(bytes.Buffer)
writer := multipart.NewWriter(body)
writer.WriteField("bu", "HFL")
writer.WriteField("wk", "10")
part, _ := writer.CreateFormFile("file", "file.csv")
part.Write([]byte(`sample`))
writer.Close() // <<< important part
e := echo.New()
req := httptest.NewRequest(http.MethodPost, "/endpoint", body)
req.Header.Set("Content-Type", writer.FormDataContentType()) // <<< important part
rec := httptest.NewRecorder()
c := e.NewContext(req, rec)
...
}
说明。 当您关闭 multipart.Writer 时,实际上会将边界 ID 写入 body(这是非常重要的部分!)。该 id 稍后使用 writer.FormDataContentType().
写入 headers事情是当你调用 FormValue、FormFile 等时调用 req.ParseMultipartForm(),后者又去寻找 multipart/form-data header 中的边界 ID,然后使用said id 搜索 body 数据。