1

I use echo framework with Custom Context:

ApiContext struct {
    echo.Context
    UserID   int64
    UserRole string
}

my middleware:

e.Use(func(h echo.HandlerFunc) echo.HandlerFunc {
    return func(c echo.Context) error {
        cc := &common.ApiContext{c, 0, ""}
        return h(cc)
    }
})

my handler:

func (app *App) listEntity(c echo.Context) error {

    ctx := c.(*ApiContext) // error!
....
}

my test:

func TestlistEntity(t *testing.T){

    e := echo.New()

    req := httptest.NewRequest(echo.GET, "/", nil)
    rec := httptest.NewRecorder()
    c := e.NewContext(req, rec)
    c.SetPath("/api/v1/entity/list")


    if assert.NoError(t, EntityList(c)) {
        assert.Equal(t, http.StatusOK rec.Code)
    }
}

i got this error:

panic: interface conversion: echo.Context is *echo.context, not *common.ApiContext

in handler function type assertion

How correctly to write the test? ps. this method working fine.

Increasingly Idiotic
  • 5,700
  • 5
  • 35
  • 73
happy_yar
  • 61
  • 1
  • 4

2 Answers2

3

So the method is not really fine, when it can panic. You could catch that error very simple:

ctx, ok := c.(*ApiContext) 
if !ok {
  // do something when you have a different type
  // return an error here
}

I think you should not use a different context then echo.Context, because just with that context the testing is supported.

But back to your question. If you want to test it with your context you need to pass your context into the test and not the echo.Context.

apxp
  • 5,240
  • 4
  • 23
  • 43
  • passed his context in the tests - works! why use custom context is bad practice? – happy_yar Aug 13 '18 at 22:29
  • It try to answer it as comment: Code should be readable, you read code more often then writing it. The `echo.Context` is the standard and when reading the code everybody expects that this part is the standard. Maybe only you knows that in some cases that thing is also something different. Maybe after 2 months also you don't know this anymore. – apxp Aug 14 '18 at 04:59
  • I am stuck with the same problem @happy_yar can you tell how did you pass the custom context in the test function? – mr-karan Aug 29 '18 at 16:13
0

Before:

if assert.NoError(t, EntityList(c)) {
    assert.Equal(t, http.StatusOK rec.Code)
}

After (Literally put in your custom context):

if assert.NoError(t, EntityList(&common.ApiContext{c, 0, ""})) {
    assert.Equal(t, http.StatusOK rec.Code)
}

However, using the standard context.Context is better practice.

snassr
  • 1,228
  • 14
  • 10