fauzanrazandi
fauzanrazandi

Reputation: 299

Multiple httptest.NewRequest with different condition in Go Test

I am still new in Golang. Do you have any ideas on how to create a multiple httptest.NewRequest efficiently in your Go test file? Usually I initiate a new variable two create new request.

For instance :

r1 := httptest.NewRequest("GET", url, nil)
r1.Header.Add("Accept-Language", "id")
r1.AddCookie(&cookie)

r2 := httptest.NewRequest("GET", url, nil)
r1.Header.Add("Accept-Language", "id")

So I want to create 2 different request, in fact I have to initiate 2 variable in order to generate new request. I also uses test table so I can't add the cookie after the first test is running.

Upvotes: 0

Views: 3020

Answers (2)

Nisarg Bhagavantanavar
Nisarg Bhagavantanavar

Reputation: 353

I did used Multiple httptest.NewRequest with different condition in Go Test

the key is to reinitialize - this worked for me to test multiple scenario

rr =  httptest.NewRecorder()

for example

t.Run("should continue to next handler when scope are valid and permission are not valid", func(t *testing.T) {
        isFunctionInvoked = false

        rr := httptest.NewRecorder()
        // creates a test context and gin engine
        _, r := gin.CreateTestContext(rr)
        r.Use(func(c *gin.Context) {
            c.Set(AUTH_RESPONSE, ir)
        })

        r.GET("/me", HasPermissionsOrHasScope(&[]string{"invalidPermission"}, "validScope"), func(context *gin.Context) {
            isFunctionInvoked = true
            return
        })

        r.GET("/me/test2", HasPermissionsOrHasScope(&[]string{"invalidPermission"}, "validScope2"), func(context *gin.Context) {
            isFunctionInvoked = true
            return
        })

        request, _ := http.NewRequest(http.MethodGet, "/me", http.NoBody)
        
        rr =  httptest.NewRecorder()
        isFunctionInvoked = false
        r.ServeHTTP(rr, request)
        assert.Equal(t, true, isFunctionInvoked)
        assert.Equal(t, http.StatusOK, rr.Code)

        request2, _ := http.NewRequest(http.MethodGet, "/me/test2", http.NoBody)
        isFunctionInvoked = false
        rr =  httptest.NewRecorder()
        r.ServeHTTP(rr, request2)
        assert.Equal(t, http.StatusOK, rr.Code)
    })

There might be better way using Test Table.

The problem i faced is, during assertion if i make scopes invalid it was giving 200 because rr := httptest.NewRecorder() rr used old response, to overcome that i need to reset rr everytime

Upvotes: 1

icza
icza

Reputation: 417622

There is little reason to optimize tests for performance, as tests don't get compiled into your app and they don't run with your app; just don't do "senseless" slow things. They run "offline" to verify the correctness of your app, so performance of tests is nowhere near critical.

So write your tests to be clean and short in source code.

But that being said, you can create a utility function to create and set up similar requests, for example:

func newRequest(url string) *http.Request {
    r := httptest.NewRequest("GET", url, nil)
    r.Header.Add("Accept-Language", "id")
    return r
}

And using it to reconstruct your example:

r1 := newRequest(url)
r1.AddCookie(&cookie)

r2 := newRequest(url)

Upvotes: 3

Related Questions