테스트
Gin의 테스트 케이스 작성 방법
섹션 제목: “Gin의 테스트 케이스 작성 방법”net/http/httptest 패키지는 HTTP 테스트에 권장되는 방법입니다.
디버그 출력 억제
섹션 제목: “디버그 출력 억제”테스트에서 라우터를 생성하기 전에 gin.SetMode(gin.TestMode)를 호출하세요. 이는 Gin이 기본적으로 출력하는 디버그 수준의 라우트 등록 로그를 억제하여 테스트 출력을 깔끔하게 유지합니다. TestMain에 배치하면 패키지의 모든 테스트에 적용됩니다:
func TestMain(m *testing.M) { gin.SetMode(gin.TestMode) os.Exit(m.Run())}예제 애플리케이션
섹션 제목: “예제 애플리케이션”package main
import "github.com/gin-gonic/gin"
type User struct { Username string `json:"username"` Gender string `json:"gender"`}
func setupRouter() *gin.Engine { router := gin.Default() router.GET("/ping", func(c *gin.Context) { c.String(200, "pong") }) return router}
func postUser(router *gin.Engine) *gin.Engine { router.POST("/user/add", func(c *gin.Context) { var user User c.BindJSON(&user) c.JSON(200, user) }) return router}
func main() { router := setupRouter() router = postUser(router) router.Run(":8080")}기본 테스트
섹션 제목: “기본 테스트”package main
import ( "net/http" "net/http/httptest" "encoding/json" "testing" "strings"
"github.com/stretchr/testify/assert")
func TestPingRoute(t *testing.T) { router := setupRouter()
w := httptest.NewRecorder() req, _ := http.NewRequest("GET", "/ping", nil) router.ServeHTTP(w, req)
assert.Equal(t, 200, w.Code) assert.Equal(t, "pong", w.Body.String())}
// POST /user/add 테스트func TestPostUser(t *testing.T) { router := setupRouter() router = postUser(router)
w := httptest.NewRecorder()
// 테스트용 사용자 예제 생성 exampleUser := User{ Username: "test_name", Gender: "male", } userJson, _ := json.Marshal(exampleUser) req, _ := http.NewRequest("POST", "/user/add", strings.NewReader(string(userJson))) router.ServeHTTP(w, req)
assert.Equal(t, 200, w.Code) // 응답 바디를 exampleUser의 json 데이터와 비교 assert.Equal(t, string(userJson), w.Body.String())}테이블 기반 테스트
섹션 제목: “테이블 기반 테스트”테이블 기반 테스트는 테스트 로직을 중복하지 않고 많은 입력/출력 조합을 다룰 수 있게 합니다. 이 패턴은 관용적 Go이며 Gin과 잘 작동합니다:
func TestPingRouteTableDriven(t *testing.T) { router := setupRouter()
tests := []struct { name string method string path string wantCode int wantBody string }{ {"ping 엔드포인트", "GET", "/ping", 200, "pong"}, {"찾을 수 없음", "GET", "/nonexistent", 404, ""}, }
for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { w := httptest.NewRecorder() req, _ := http.NewRequest(tt.method, tt.path, nil) router.ServeHTTP(w, req)
assert.Equal(t, tt.wantCode, w.Code) if tt.wantBody != "" { assert.Equal(t, tt.wantBody, w.Body.String()) } }) }}미들웨어 테스트
섹션 제목: “미들웨어 테스트”미들웨어를 독립적으로 테스트하려면 미들웨어가 적용된 최소한의 라우터와 결과를 기록하는 간단한 핸들러를 생성합니다:
func TestAuthMiddleware(t *testing.T) { gin.SetMode(gin.TestMode)
// 테스트 대상 미들웨어가 적용된 라우터 생성 router := gin.New() router.Use(AuthRequired()) // 미들웨어
router.GET("/protected", func(c *gin.Context) { c.String(200, "ok") })
// 자격 증명 없이 테스트 -- 401 기대 w := httptest.NewRecorder() req, _ := http.NewRequest("GET", "/protected", nil) router.ServeHTTP(w, req) assert.Equal(t, 401, w.Code)
// 유효한 자격 증명으로 테스트 -- 200 기대 w = httptest.NewRecorder() req, _ = http.NewRequest("GET", "/protected", nil) req.Header.Set("Authorization", "Bearer valid-token") router.ServeHTTP(w, req) assert.Equal(t, 200, w.Code)}