Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ctx.Status() does not affect httptest.ResponseRecorder while ctx.JSON() does #4071

Open
cardillomarcelo opened this issue Oct 9, 2024 · 2 comments

Comments

@cardillomarcelo
Copy link

Description

ctx.Status() does not affect httptest.ResponseRecorder while ctx.JSON() does

How to reproduce

package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
	"net/http/httptest"
	"testing"
)

func TestName(t *testing.T) {
	recorder := httptest.NewRecorder()

	c, _ := gin.CreateTestContext(recorder)

	changeResponseCode(c)

	fmt.Println(recorder.Code)
}

func changeResponseCode(ctx *gin.Context) {
	ctx.Status(http.StatusNoContent)
}

Expectations

Should print 204

Actual result

Prints 200

Environment

  • go version: 1.23.2
  • gin version (or commit ref): 1.10.0
  • operating system: Ubuntu 22.04
@JimChenWYU
Copy link

image image

c.Status(204) do not change the recorder.status but change responseWriter.status

image

@ksw2000
Copy link

ksw2000 commented Nov 11, 2024

It seems that ctx.Status() In the function changeResponseCode changes the Writer in ctx but doesn't change the recorder. That is to say, you can fetch the status code by c.Writer.Status()

func TestName(t *testing.T) {
	recorder := httptest.NewRecorder()

	c, _ := gin.CreateTestContext(recorder)

	changeResponseCode(c)

	fmt.Println(c.Writer.Status())  // 204
	fmt.Println(recorder.Code)  // 200
}

Besides, I found a related unit test in response_writer_test.go

func TestResponseWriterWriteHeader(t *testing.T) {
testWriter := httptest.NewRecorder()
writer := &responseWriter{}
writer.reset(testWriter)
w := ResponseWriter(writer)
w.WriteHeader(http.StatusMultipleChoices)
assert.False(t, w.Written())
assert.Equal(t, http.StatusMultipleChoices, w.Status())
assert.NotEqual(t, http.StatusMultipleChoices, testWriter.Code)
w.WriteHeader(-1)
assert.Equal(t, http.StatusMultipleChoices, w.Status())
}

func TestResponseWriterWriteHeader(t *testing.T) {
	testWriter := httptest.NewRecorder()
	writer := &responseWriter{}
	writer.reset(testWriter)
	w := ResponseWriter(writer)

	w.WriteHeader(http.StatusMultipleChoices)
	assert.False(t, w.Written())
	assert.Equal(t, http.StatusMultipleChoices, w.Status())
	assert.NotEqual(t, http.StatusMultipleChoices, testWriter.Code)  // ← WHY ?

	w.WriteHeader(-1)
	assert.Equal(t, http.StatusMultipleChoices, w.Status())
}

I'm not sure why it was designed so that the original testWriter does not change along with it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants