gin icon indicating copy to clipboard operation
gin copied to clipboard

Unit testing redirect results in panic

Open Danoctum opened this issue 1 year ago • 3 comments

Description

When unit testing a HTTP redirect, the result will always be a panic.

How to reproduce

package main

import (
	"github.com/gin-gonic/gin"
)

func Something(c *gin.Context) {
	c.Redirect(http.StatusFound, "google.com")
}
package main_test

import (
	"github.com/gin-gonic/gin"
	"github.com/stretchr/testify/assert"
	"net/http"
	"net/http/httptest"
	"testing"
)

func TestSomething(t *testing.T) {
	w := httptest.NewRecorder()
	c, _ := gin.CreateTestContext(w)
	Something(c)
	assert.Equal(t, http.StatusFound, w.Code)
}

Expectations

I'm expecting the redirect not to panic.

Actual result

testing.tRunner.func1.2({0x1058c73e0, 0x105e3d500}) /usr/local/go/src/testing/testing.go:1526 +0x1c8 testing.tRunner.func1() /usr/local/go/src/testing/testing.go:1529 +0x384 panic({0x1058c73e0, 0x105e3d500}) /usr/local/go/src/runtime/panic.go:884 +0x204 net/http.Redirect({0x12d754dc8?, 0x14000646300}, 0x0, {0x1056d411c, 0xa}, 0x1056a74d0?) /usr/local/go/src/net/http/server.go:2190 +0x60 github.com/gin-gonic/gin/render.Redirect.Render({0x140000c6e88?, 0x0?, {0x1056d411c?, 0x1059576a0?}}, {0x12d754dc8?, 0x14000646300?}) go/pkg/mod/github.com/gin-gonic/[email protected]/render/redirect.go:24 +0x68 github.com/gin-gonic/gin.(*Context).Render(0x14000646300, 0xffffffffffffffff, {0x105992950, 0x140003e7640}) go/pkg/mod/github.com/gin-gonic/[email protected]/context.go:926 +0xf4 github.com/gin-gonic/gin.(*Context).Redirect(...) go/pkg/mod/github.com/gin-gonic/[email protected]/context.go:1014 src/auth.Something(...) src/auth/auth.go:21 src/auth_test.TestSomething(0x0?) src/auth/auth_test.go:24 +0x100

Environment

  • go version: go1.21.4 darwin/arm64 (also tested with go1.20.5 darwin/arm64)
  • gin version (or commit ref): v1.9.1
  • operating system: MacOS Sanoma with Apple Silicon

Danoctum avatar Nov 08 '23 18:11 Danoctum

Created a minimal repo here: https://github.com/Danoctum/gin-redirect-panic

Danoctum avatar Nov 08 '23 19:11 Danoctum

I was able to reproduce it in my environment.

if userId == nil {
	c.Redirect(http.StatusTemporaryRedirect, "/login")
}

For it to work, it was necessary to use net/http to redirect.

if userId == nil {
	// c.Redirect(http.StatusTemporaryRedirect, "/login")
	http.Redirect(c.Writer, c.Request, "/login", http.StatusTemporaryRedirect)
}

vinhais avatar Nov 09 '23 04:11 vinhais

Hi @Danoctum and @vinhais

The Nil panic happens as the gin context Request field is nil, you can simply fix it like this

package testgin

import (
	"net/http"

	"github.com/gin-gonic/gin"
)

func Something(c *gin.Context) {
	c.Redirect(http.StatusFound, "google.com")
}
package testgin_test

import (
	testgin "gingonic"
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/gin-gonic/gin"
	"github.com/stretchr/testify/assert"
)

func TestSomething(t *testing.T) {
	w := httptest.NewRecorder()
	c, _ := gin.CreateTestContext(w)
	c.Request, _ = http.NewRequest(http.MethodGet, "/something", nil)
	testgin.Something(c)
	assert.Equal(t, http.StatusFound, w.Code)
}

Note: Please check out gin documentation https://gin-gonic.com/docs/testing for the proper way of testing gin application.

Rishikesh01 avatar Nov 23 '23 16:11 Rishikesh01