How to write unit test case using golang echo, when we have multipart form files and json request? #2378
Answered
by
aldas
SajaiPrathap070
asked this question in
Q&A
-
In the request handler we are reading form value using c.FormValue and multipart files using c.MultipartForm. but I am not sure how to write the unit test case for handling multipart files. For more details pls look into the below code: Handler code: func (h *testimonialHandlers) UpdateTestimonial(c echo.Context) error {
jsonValue := c.FormValue("json")
if len(jsonValue) == 0 {
log.Errorf("Error: %#v - Input: %#v\n", jsonValue, nil)
return errorResponse(c, http.StatusBadRequest, "json is empty")
}
var testimonialModel business.Testimonial
if err := json.Unmarshal([]byte(jsonValue), &testimonialModel); err != nil {
log.Errorf("Error: %#v - Input: %#v\n", err, jsonValue)
return errorResponse(c, http.StatusBadRequest, "error while unmarshalling the json")
}
if err := c.Validate(&testimonialModel); err != nil {
log.Errorf("Error: %#v - Input: %#v\n", err, testimonialModel)
return errorResponse(c, http.StatusBadRequest, "Required field is empty!")
}
var files []*multipart.FileHeader = nil
if testimonialModel.Type == business.IMAGE || testimonialModel.Type == business.VIDEO {
form, err := c.MultipartForm()
if err != nil {
log.Errorf("Error: %#v - Input: %#v\n", err, form)
return errorResponse(c, http.StatusBadRequest, "error while reading multi-part form")
}
files = form.File["file"]
}
if updateResult, err := h.service.UpdateTestimonial(testimonialModel, files); err == nil && len(updateResult) > 1 {
var status = transport.Status{Code: http.StatusOK, Msg: "Successful"}
var data = transport.CreateData{Flag: true, Message: "Created", Id: updateResult}
return c.JSON(status.Code, transport.CreateResponse{Status: status, Data: data})
} else {
log.Errorf("Error: %#v - Input: %#v\n", err, testimonialModel)
return errorResponse(c, http.StatusInternalServerError, "Failed to update or create!")
}
} Unit test case code: func TestTestimonialsHandlers_UpdateTestimonial(t *testing.T) {
var testCases = []struct {
name string
whenPayload string
dBWhen business.Testimonial
dBReturn int64
dBError error
expect string
expectError string
}{
{ // create testimonial
name: "ok, happy case",
whenPayload: `{"type":1, "uid": "000000000000000000000000","apv":true, "rank":1, "ttl": "Lost 5kg in 3 months. from 100kg to 95kg", "text": "I plan to use this for a long time!", "mda": [{"name": "Banner3.png", "ttl": "before image", "url": "/62fcd8c098eb9d5ed0380000/testimonial/Banner3.png"},{"name": "Banner4.png", "ttl": "after image", "url": "/62fcd8c098eb9d5ed0380000/testimonial/Banner4.png"}], "user": {"name": "christina", "org": "EkoHunt", "role": "CTO", "url": "/profile/Avatar6.png"}}`, // ID could be sent
dBWhen: business.Testimonial{Type: 1, UserId: "000000000000000000000000", Approve: true, Rank: 1, Title: "Lost 5kg in 3 months. from 100kg to 95kg", Text: "I plan to use this for a long time!", Media: []business.Media{{Name: "Banner3.png", Title: "before image", URL: "/62fcd8c098eb9d5ed0380000/testimonial/Banner3.png"}, {Name: "Banner4.png", Title: "after image", URL: "/62fcd8c098eb9d5ed0380000/testimonial/Banner4.png"}}, User: business.User{Name: "christina", Org: "EkoHunt", Role: "CTO", URL: "/profile/Avatar6.png"}},
dBReturn: 999,
expect: `{"status": {"code": 200, "msg": "Successful"}, "data": {"flag": true, "msg": "Created", "id": "63495993a422ac8329667e86"}}`,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
database := new(dbTestimonialsMock)
database.On("UpdateTestimonial", tc.dBWhen).Return(tc.dBReturn, tc.dBError)
req := httptest.NewRequest(http.MethodPut, fmt.Sprintf("/put/?json=%s", tc.whenPayload), nil)
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
rec := httptest.NewRecorder()
e := echo.New()
c := e.NewContext(req, rec)
e.Validator = &CustomValidator{Validator: validator.New()} //for custom validator
h := testimonialHandlers{service: database}
err := h.UpdateTestimonial(c)
assert.JSONEq(t, tc.expect, string(rec.Body.Bytes()))
if tc.expectError != "" {
assert.EqualError(t, err, tc.expectError)
} else {
assert.NoError(t, err)
}
})
}
} |
Beta Was this translation helpful? Give feedback.
Answered by
aldas
Jan 19, 2023
Replies: 1 comment
-
Try something like this func TestMultiPartForm(t *testing.T) {
e := echo.New()
bodyBuffer := new(bytes.Buffer)
mw := multipart.NewWriter(bodyBuffer) // see https://pkg.go.dev/mime/multipart
mw.WriteField("id", "1")
mw.WriteField("json", `{"ok":true}`)
mw.Close()
req := httptest.NewRequest(http.MethodPost, "/", bodyBuffer)
rec := httptest.NewRecorder()
req.Header.Set(echo.HeaderContentType, mw.FormDataContentType())
c := e.NewContext(req, rec)
type payload = struct {
ID int `form:"id"`
JSON string `form:"json"`
}
u := new(payload)
err := c.Bind(u)
if assert.NoError(t, err) {
assert.Equal(t, 1, u.ID)
assert.Equal(t, `{"ok":true}`, u.JSON)
}
} and if you need to add file to that multipartform part, err := mw.CreateFormFile("file", "myfile.txt")
if err != nil {
t.Fatal(err)
}
file := strings.NewReader(`contents of my file`)
io.Copy(part, file) |
Beta Was this translation helpful? Give feedback.
0 replies
Answer selected by
lammel
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Try something like this
and if you nee…