gin icon indicating copy to clipboard operation
gin copied to clipboard

Using test context in handlerfunc test

Open madiganz opened this issue 6 years ago • 7 comments

I am trying to write tests around my handler functions and middleware functions, but the context is not being passed to the handlerfunc, and I am not sure why.

My code looks like this:

resp := httptest.NewRecorder()
gin.SetMode(gin.TestMode)
c, r := gin.CreateTestContext(resp)
c.Set("profile", "myfakeprofile")
r.GET("/test", func(c *gin.Context) {
    _, found := c.Get("profile")
    // found is always false    
    t.Log(found)
    c.Status(200)
})
c.Request, _ = http.NewRequest(http.MethodGet, "/test", nil)
r.ServeHTTP(resp, c.Request)

madiganz avatar Mar 21 '18 20:03 madiganz

@madiganz please see https://github.com/gin-gonic/gin/blob/master/context_test.go#L179

IMPORTANT: the c' of _, found := c.Get("profile"is not thecofc, r := gin.CreateTestContext, so found is always false`.

thinkerou avatar Jun 24 '18 06:06 thinkerou

So based on that example, there is no way to do what I am trying to do, correct?

madiganz avatar Jun 25 '18 16:06 madiganz

If you want to use Set/Get, you should read the example https://github.com/gin-gonic/gin#custom-middleware

thinkerou avatar Jun 26 '18 01:06 thinkerou

@thinkerou I understand how to use Set/`Get'. I just can't create a test for my middleware based on the first link you sent to me.

madiganz avatar Jun 26 '18 16:06 madiganz

I am also interested in being able to test how an endpoint handles things that are in the context without doing fully fledged integration tests. After adding things to the context created by gin.CreateTestContext(), can the edited context then be injected into the engine? Or is it possible to define context stuff in another way so it isn't just a standard/empty context that is created in gin.CreateTestContext()?

sfro avatar Feb 13 '19 13:02 sfro

After playing around a bit I worked it out:

resp := httptest.NewRecorder()
gin.SetMode(gin.TestMode)
c, r := gin.CreateTestContext(resp)

r.Use(func(c *gin.Context) {
	c.Set("profile", "myfakeprofile")
})

r.GET("/test", func(c *gin.Context) {
	_, found := c.Get("profile")
	// found is true
	t.Log(found)
	c.Status(200)
})
c.Request, _ = http.NewRequest(http.MethodGet, "/test", nil)
r.ServeHTTP(resp, c.Request)

sfro avatar Feb 13 '19 14:02 sfro

I think that gin.CreateTestContext() is also useful to test the middleware in isolation without the involvement of the engine.

func MyHandlerFunc() gin.HandlerFunc {
	return func(c *gin.Context) {
		c.Set("profile", "myfakeprofile")
	}
}

func TestMyHandlerFunc(t *testing.T) {
	recorder := httptest.NewRecorder()
	ctx, _ := gin.CreateTestContext(recorder)
	MyHandlerFunc()(ctx)
        got := ctx.GetString("profile")
	t.Log(got) // "myfakeprofile"
}

twocs avatar Mar 18 '24 23:03 twocs