Echo: How to test a handler that return 404 ?

Created on 6 Jul 2016  路  8Comments  路  Source: labstack/echo

Description

My handler return a 404, but I cannot test the status code returned as the code does not reach my custom ErrorHandler.

Is there any way I can test the actuel status code in my test ?

I would like to test something like that

assert.Equal(t, http.StatusNotFound, rec.Code)

The handler :

func  (h *Handler)Ipsum(c echo.Context) error {

    ipsumMap, err := h.Dbm.GetIpsum( c.Param("uri") )

    // return 404 when there is not match in the DB
    if ( err != nil ) {
        return echo.NewHTTPError(http.StatusNotFound, err.Error())
    }

The test :

func TestIpsum(t *testing.T) {
    dbm, _ := db.NewSqliteManager("./TestIpsum.db")
    defer db.AfterDbTest(dbm,"./TestIpsum.db")()

    test.LoadTestData("./TestIpsum.db","./app_test.TestIpsum.sql")

    h = &Handler{dbm}

    e, req, rec := test.GetEcho(), new(http.Request), httptest.NewRecorder()
    c := e.NewContext(standard.NewRequest(req, e.Logger()), standard.NewResponse(rec, e.Logger()))

    c.SetPath("/:uri")
    c.SetParamNames("uri")
    c.SetParamValues("i-dont-exist")

    assert.Error(t, h.Ipsum(c))
}

Custom ErrorHandler

func ErrorHandler(err error, c echo.Context) {
    code := http.StatusInternalServerError
    msg := http.StatusText(code)
    he, ok := err.(*echo.HTTPError)
    if ok {

        code = he.Code
        msg = he.Message
        fmt.Printf("ErrorHandler msg :%v for URI =%v \n",msg, c.Request().URI())
        switch code {
        case http.StatusNotFound:
            c.Render(code, "404","")
        default:
            c.Render(code, "404",msg)
        }
    }
}
question

Most helpful comment

Make sense ! thank you so much , code below works

    err := h.Ipsum(c)
    if( assert.NotNil(t,err) ){
        he, ok := err.(*echo.HTTPError)
        if ok {
            assert.Equal(t, http.StatusNotFound, he.Code)
        } 
    }

All 8 comments

You response is recorded in rec so assert.Equal(t, http. StatusNotFound, rec.Code). From https://echo.labstack.com/guide/testing

Unfortunately I tried it, and status is 200, rec.Body = "", I don't reach the ErrorHandler (I've put printf in there).

Also, I'm sure the return echo.NewHTTPError(http.StatusNotFound, err.Error()) is reached as I get the err back in the test.

Custom error handler only plays with real request. Are you able to test your handler (standalone) for 404 code?

What do you mean standalone ? I thought this one was :+1:

func TestIpsum(t *testing.T) {
    dbm, _ := db.NewSqliteManager("./TestIpsum.db")
    defer db.AfterDbTest(dbm,"./TestIpsum.db")()

    test.LoadTestData("./TestIpsum.db","./app_test.TestIpsum.sql")

    h = &Handler{dbm}

    e, req, rec := test.GetEcho(), new(http.Request), httptest.NewRecorder()
    c := e.NewContext(standard.NewRequest(req, e.Logger()), standard.NewResponse(rec, e.Logger()))

    c.SetPath("/:uri")
    c.SetParamNames("uri")
    c.SetParamValues("i-dont-exist")

    assert.Error(t, h.Ipsum(c))
}

In the test above the recorded status is 200 , even if

return echo.NewHTTPError(http.StatusNotFound, err.Error())

is executed

For 404 your handler is just returning an error, rec will be filled only if it writes to the response. You should test for error like he, ok := err.(*echo.HTTPError) and check status code in he.

Make sense ! thank you so much , code below works

    err := h.Ipsum(c)
    if( assert.NotNil(t,err) ){
        he, ok := err.(*echo.HTTPError)
        if ok {
            assert.Equal(t, http.StatusNotFound, he.Code)
        } 
    }

Could this be added to the documentation ?

Could this be added to the documentation ?

Yea, that is not at all clear from the documentation. I definitely expected to use the rec object to check errors as well.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

spielstein picture spielstein  路  3Comments

alexzorin picture alexzorin  路  3Comments

absinsekt picture absinsekt  路  4Comments

wangxianzhuo picture wangxianzhuo  路  4Comments

kyokomi picture kyokomi  路  3Comments