Minor test improvements

This commit is contained in:
Dan Jones 2025-07-08 11:32:06 -05:00
commit 18d987caf7
3 changed files with 59 additions and 50 deletions

View file

@ -23,6 +23,11 @@ linters:
- gosec - gosec
- perfsprint - perfsprint
- testifylint - testifylint
exclusions:
rules:
- path: _test\.go
linters:
- err113
settings: settings:
testifylint: testifylint:
enable-all: true enable-all: true

View file

@ -10,17 +10,31 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
var ( var errTest = errors.New("test error")
errTest = errors.New("test error")
type handlerType string
const (
handlerT handlerType = "Handler"
handlerFuncT handlerType = "HandlerFunc"
respHandlerT handlerType = "ResponseHandler"
) )
type testHandler struct {
err error
}
func (th testHandler) ServeHTTP(http.ResponseWriter, *http.Request) error {
return th.err
}
func TestNewHelper(t *testing.T) { func TestNewHelper(t *testing.T) {
mockErrorHandler := func(w http.ResponseWriter, r *http.Request, err error) {} mockErrorHandler := func(w http.ResponseWriter, r *http.Request, err error) {}
helper := ezhandler.NewHelper(mockErrorHandler) helper := ezhandler.NewHelper(mockErrorHandler)
assert.NotNil(t, helper) assert.NotNil(t, helper)
} }
func runHelperTest(t *testing.T, name string, handlerErr, expectedErr error, expectedErrorHandlerCalled bool, handlerType string) { func runHelperTest(t *testing.T, name string, handlerErr, expectedErr error, expectedErrorHandlerCalled bool, ht handlerType) {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
var errorHandlerCalled bool var errorHandlerCalled bool
mockErrorHandler := func(w http.ResponseWriter, r *http.Request, err error) { mockErrorHandler := func(w http.ResponseWriter, r *http.Request, err error) {
@ -33,18 +47,16 @@ func runHelperTest(t *testing.T, name string, handlerErr, expectedErr error, exp
rec := httptest.NewRecorder() rec := httptest.NewRecorder()
var wrappedHandler http.Handler var wrappedHandler http.Handler
switch handlerType { switch ht {
case "Handler": case handlerT:
mockHandler := ezhandler.HandlerFunc(func(w http.ResponseWriter, r *http.Request) error { mockHandler := testHandler{handlerErr}
return handlerErr
})
wrappedHandler = helper.Handler(mockHandler) wrappedHandler = helper.Handler(mockHandler)
case "HandlerFunc": case handlerFuncT:
mockHandlerFunc := ezhandler.HandlerFunc(func(w http.ResponseWriter, r *http.Request) error { mockHandlerFunc := ezhandler.HandlerFunc(func(w http.ResponseWriter, r *http.Request) error {
return handlerErr return handlerErr
}) })
wrappedHandler = helper.HandlerFunc(mockHandlerFunc) wrappedHandler = helper.HandlerFunc(mockHandlerFunc)
case "ResponderHandler": case respHandlerT:
mockResponseHandler := ezhandler.ResponseHandler(func(r *http.Request) (ezhandler.ResponseHelper, error) { mockResponseHandler := ezhandler.ResponseHandler(func(r *http.Request) (ezhandler.ResponseHelper, error) {
if handlerErr != nil { if handlerErr != nil {
return nil, handlerErr return nil, handlerErr
@ -52,6 +64,8 @@ func runHelperTest(t *testing.T, name string, handlerErr, expectedErr error, exp
return ezhandler.JSONResponse(map[string]string{"status": "ok"}), nil return ezhandler.JSONResponse(map[string]string{"status": "ok"}), nil
}) })
wrappedHandler = helper.ResponderHandler(mockResponseHandler) wrappedHandler = helper.ResponderHandler(mockResponseHandler)
default:
assert.Fail(t, "Unknown test type: "+string(ht))
} }
wrappedHandler.ServeHTTP(rec, req) wrappedHandler.ServeHTTP(rec, req)
@ -61,16 +75,16 @@ func runHelperTest(t *testing.T, name string, handlerErr, expectedErr error, exp
} }
func TestHelper_Handler(t *testing.T) { func TestHelper_Handler(t *testing.T) {
runHelperTest(t, "no error", nil, nil, false, "Handler") runHelperTest(t, "no error", nil, nil, false, handlerT)
runHelperTest(t, "with error", errTest, errTest, true, "Handler") runHelperTest(t, "with error", errTest, errTest, true, handlerT)
} }
func TestHelper_HandlerFunc(t *testing.T) { func TestHelper_HandlerFunc(t *testing.T) {
runHelperTest(t, "no error", nil, nil, false, "HandlerFunc") runHelperTest(t, "no error", nil, nil, false, handlerFuncT)
runHelperTest(t, "with error", errTest, errTest, true, "HandlerFunc") runHelperTest(t, "with error", errTest, errTest, true, handlerFuncT)
} }
func TestHelper_ResponderHandler(t *testing.T) { func TestHelper_ResponderHandler(t *testing.T) {
runHelperTest(t, "no error", nil, nil, false, "ResponderHandler") runHelperTest(t, "no error", nil, nil, false, respHandlerT)
runHelperTest(t, "with error", errTest, errTest, true, "ResponderHandler") runHelperTest(t, "with error", errTest, errTest, true, respHandlerT)
} }

View file

@ -1,17 +1,15 @@
package ezhandler_test package ezhandler_test
import ( import (
"codeberg.org/danjones000/ezhandler"
"encoding/json" "encoding/json"
"errors" "errors"
"github.com/stretchr/testify/assert"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"testing" "testing"
)
var errCircularMarshal = errors.New("json: unsupported value: encountered a cycle") "codeberg.org/danjones000/ezhandler"
"github.com/stretchr/testify/assert"
)
func TestJSONResponse(t *testing.T) { func TestJSONResponse(t *testing.T) {
type testData struct { type testData struct {
@ -76,18 +74,20 @@ func TestJSONResponse_BodyError(t *testing.T) {
assert.Nil(t, body) assert.Nil(t, body)
} }
type jsonServeTestCase struct {
name string
handler ezhandler.ResponseHandler
expectedStatus int
expectedBody string
expectedError error
}
func TestResponseHandler_ServeHTTP_JSONResponse(t *testing.T) { func TestResponseHandler_ServeHTTP_JSONResponse(t *testing.T) {
type testData struct { type testData struct {
Message string `json:"message"` Message string `json:"message"`
} }
tests := []struct { tests := []jsonServeTestCase{
name string
handler ezhandler.ResponseHandler
expectedStatus int
expectedBody string
expectedError error
}{
{ {
name: "successful JSON response", name: "successful JSON response",
handler: ezhandler.ResponseHandler(func(r *http.Request) (ezhandler.ResponseHelper, error) { handler: ezhandler.ResponseHandler(func(r *http.Request) (ezhandler.ResponseHelper, error) {
@ -111,9 +111,7 @@ func TestResponseHandler_ServeHTTP_JSONResponse(t *testing.T) {
handler: ezhandler.ResponseHandler(func(r *http.Request) (ezhandler.ResponseHelper, error) { handler: ezhandler.ResponseHandler(func(r *http.Request) (ezhandler.ResponseHelper, error) {
return nil, errTest // Using errTest from helper_test.go return nil, errTest // Using errTest from helper_test.go
}), }),
expectedStatus: http.StatusOK, // Status won't be set if handler returns error before writing header expectedError: errTest,
expectedBody: "",
expectedError: errTest,
}, },
{ {
name: "error from Body() method", name: "error from Body() method",
@ -125,37 +123,29 @@ func TestResponseHandler_ServeHTTP_JSONResponse(t *testing.T) {
data.Self = &data data.Self = &data
return ezhandler.JSONResponse(data), nil return ezhandler.JSONResponse(data), nil
}), }),
expectedStatus: http.StatusOK, // Status won't be set if Body() returns error expectedError: errors.New("json: unsupported value: encountered a cycle"), // The error is returned by ServeHTTP, not the handler func
expectedBody: "",
expectedError: errCircularMarshal, // The error is returned by ServeHTTP, not the handler func
}, },
} }
for _, tt := range tests { for _, tc := range tests {
runResponseHandlerTest(t, tt) runResponseHandlerTest(t, tc)
} }
} }
func runResponseHandlerTest(t *testing.T, tt struct { func runResponseHandlerTest(tt *testing.T, tc jsonServeTestCase) {
name string tt.Run(tc.name, func(t *testing.T) {
handler ezhandler.ResponseHandler
expectedStatus int
expectedBody string
expectedError error
}) {
t.Run(tt.name, func(t *testing.T) {
req := httptest.NewRequest(http.MethodGet, "/", http.NoBody) req := httptest.NewRequest(http.MethodGet, "/", http.NoBody)
rec := httptest.NewRecorder() rec := httptest.NewRecorder()
err := tt.handler.ServeHTTP(rec, req) err := tc.handler.ServeHTTP(rec, req)
if tt.expectedError != nil { if tc.expectedError != nil {
assert.ErrorContains(t, err, tt.expectedError.Error()) assert.ErrorContains(t, err, tc.expectedError.Error())
} else { } else {
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, tt.expectedStatus, rec.Code) assert.Equal(t, tc.expectedStatus, rec.Code)
assert.Equal(t, tt.expectedBody, rec.Body.String()) assert.Equal(t, tc.expectedBody, rec.Body.String())
if tt.expectedBody != "" { if tc.expectedBody != "" {
assert.Equal(t, "application/json", rec.Header().Get("Content-Type")) assert.Equal(t, "application/json", rec.Header().Get("Content-Type"))
} }
} }