Testing

Testing Handler

GET /users/:id

Handler below retrieves user by id from the database. If user is not found it returns 404 error with a message.

CreateUser

POST /users

  • Accepts JSON payload
  • On success 201 - Created
  • On error 500 - Internal Server Error

GetUser

GET /users/:email

  • On success 200 - OK
  • On error 404 - Not Found if user is not found otherwise 500 - Internal Server Error

handler.go

  1. package handler
  2. import (
  3. "net/http"
  4. "github.com/labstack/echo/v4"
  5. )
  6. type (
  7. User struct {
  8. Name string `json:"name" form:"name"`
  9. Email string `json:"email" form:"email"`
  10. }
  11. handler struct {
  12. db map[string]*User
  13. }
  14. )
  15. func (h *handler) createUser(c echo.Context) error {
  16. u := new(User)
  17. if err := c.Bind(u); err != nil {
  18. return err
  19. }
  20. return c.JSON(http.StatusCreated, u)
  21. }
  22. func (h *handler) getUser(c echo.Context) error {
  23. email := c.Param("email")
  24. user := h.db[email]
  25. if user == nil {
  26. return echo.NewHTTPError(http.StatusNotFound, "user not found")
  27. }
  28. return c.JSON(http.StatusOK, user)
  29. }

handler_test.go

  1. package handler
  2. import (
  3. "net/http"
  4. "net/http/httptest"
  5. "strings"
  6. "testing"
  7. "github.com/labstack/echo/v4"
  8. "github.com/stretchr/testify/assert"
  9. )
  10. var (
  11. mockDB = map[string]*User{
  12. "[email protected]": &User{"Jon Snow", "[email protected]"},
  13. }
  14. userJSON = `{"name":"Jon Snow","email":"[email protected]"}`
  15. )
  16. func TestCreateUser(t *testing.T) {
  17. // Setup
  18. e := echo.New()
  19. req := httptest.NewRequest(http.MethodPost, "/", strings.NewReader(userJSON))
  20. req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
  21. rec := httptest.NewRecorder()
  22. c := e.NewContext(req, rec)
  23. h := &handler{mockDB}
  24. // Assertions
  25. if assert.NoError(t, h.createUser(c)) {
  26. assert.Equal(t, http.StatusCreated, rec.Code)
  27. assert.Equal(t, userJSON, rec.Body.String())
  28. }
  29. }
  30. func TestGetUser(t *testing.T) {
  31. // Setup
  32. e := echo.New()
  33. req := httptest.NewRequest(http.MethodGet, "/", nil)
  34. rec := httptest.NewRecorder()
  35. c := e.NewContext(req, rec)
  36. c.SetPath("/users/:email")
  37. c.SetParamNames("email")
  38. c.SetParamValues("[email protected]")
  39. h := &handler{mockDB}
  40. // Assertions
  41. if assert.NoError(t, h.getUser(c)) {
  42. assert.Equal(t, http.StatusOK, rec.Code)
  43. assert.Equal(t, userJSON, rec.Body.String())
  44. }
  45. }

Using Form Payload

  1. // import "net/url"
  2. f := make(url.Values)
  3. f.Set("name", "Jon Snow")
  4. f.Set("email", "[email protected]")
  5. req := httptest.NewRequest(http.MethodPost, "/", strings.NewReader(f.Encode()))
  6. req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationForm)

Setting Path Params

  1. c.SetParamNames("id", "email")
  2. c.SetParamValues("1", "[email protected]")

Setting Query Params

  1. // import "net/url"
  2. q := make(url.Values)
  3. q.Set("email", "[email protected]")
  4. req := httptest.NewRequest(http.MethodGet, "/?"+q.Encode(), nil)

Testing Middleware

TBD

For now you can look into built-in middleware test cases.