Skip to content

Commit 7b8d829

Browse files
committed
Improve unit tests on middlewares
Signed-off-by: Xabier Larrakoetxea <[email protected]>
1 parent ae1558d commit 7b8d829

File tree

14 files changed

+335
-277
lines changed

14 files changed

+335
-277
lines changed

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ require (
77
github.com/julienschmidt/httprouter v1.3.0
88
github.com/labstack/echo/v4 v4.1.16
99
github.com/prometheus/client_golang v1.6.0
10-
github.com/stretchr/testify v1.5.1
10+
github.com/stretchr/testify v1.6.0
1111
github.com/urfave/negroni v1.0.0
1212
go.opencensus.io v0.22.3
1313
)

go.sum

+5-2
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9
106106
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
107107
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
108108
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
109+
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
109110
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
110111
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
111112
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ -143,8 +144,8 @@ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0
143144
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
144145
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
145146
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
146-
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
147-
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
147+
github.com/stretchr/testify v1.6.0 h1:jlIyCplCJFULU/01vCkhKuTyc3OorI3bJFuw6obfgho=
148+
github.com/stretchr/testify v1.6.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
148149
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
149150
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
150151
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
@@ -241,4 +242,6 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
241242
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
242243
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
243244
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
245+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
246+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
244247
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

middleware/echo/echo.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
// Package echo is a helper package to get an echo compatible
2-
// handler/middleware from the standard net/http Middleware factory.
1+
// Package echo is a helper package to get an echo compatible middleware
32
package echo
43

54
import (

middleware/echo/echo_test.go

+52-40
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,91 @@
11
package echo_test
22

33
import (
4+
"io/ioutil"
45
"net/http"
56
"net/http/httptest"
67
"testing"
78

89
"github.com/labstack/echo/v4"
10+
"github.com/stretchr/testify/assert"
11+
"github.com/stretchr/testify/mock"
12+
"github.com/stretchr/testify/require"
13+
914
mmetrics "github.com/slok/go-http-metrics/internal/mocks/metrics"
1015
"github.com/slok/go-http-metrics/metrics"
1116
"github.com/slok/go-http-metrics/middleware"
1217
echoMiddleware "github.com/slok/go-http-metrics/middleware/echo"
13-
"github.com/stretchr/testify/assert"
14-
"github.com/stretchr/testify/mock"
1518
)
1619

17-
func getTestHandler(statusCode int) echo.HandlerFunc {
18-
return func(context echo.Context) error {
19-
context.Response().WriteHeader(statusCode)
20-
return nil
21-
}
22-
}
23-
2420
func TestMiddleware(t *testing.T) {
2521
tests := map[string]struct {
26-
handlerID string
27-
statusCode int
28-
req *http.Request
29-
config middleware.Config
30-
expHandlerID string
31-
expService string
32-
expMethod string
33-
expStatusCode string
22+
handlerID string
23+
config middleware.Config
24+
req func() *http.Request
25+
mock func(m *mmetrics.Recorder)
26+
handler func() echo.HandlerFunc
27+
expRespCode int
28+
expRespBody string
3429
}{
3530
"A default HTTP middleware should call the recorder to measure.": {
36-
statusCode: http.StatusAccepted,
37-
req: httptest.NewRequest(http.MethodPost, "/test", nil),
38-
expHandlerID: "/test",
39-
expMethod: http.MethodPost,
40-
expStatusCode: "202",
31+
req: func() *http.Request {
32+
return httptest.NewRequest(http.MethodPost, "/test", nil)
33+
},
34+
mock: func(m *mmetrics.Recorder) {
35+
expHTTPReqProps := metrics.HTTPReqProperties{
36+
ID: "/test",
37+
Service: "",
38+
Method: "POST",
39+
Code: "202",
40+
}
41+
m.On("ObserveHTTPRequestDuration", mock.Anything, expHTTPReqProps, mock.Anything).Once()
42+
m.On("ObserveHTTPResponseSize", mock.Anything, expHTTPReqProps, int64(5)).Once()
43+
44+
expHTTPProps := metrics.HTTPProperties{
45+
ID: "/test",
46+
Service: "",
47+
}
48+
m.On("AddInflightRequests", mock.Anything, expHTTPProps, 1).Once()
49+
m.On("AddInflightRequests", mock.Anything, expHTTPProps, -1).Once()
50+
},
51+
handler: func() echo.HandlerFunc {
52+
return func(context echo.Context) error {
53+
resp := context.Response()
54+
resp.WriteHeader(202)
55+
_, err := resp.Write([]byte("test1"))
56+
return err
57+
}
58+
},
59+
expRespCode: 202,
60+
expRespBody: "test1",
4161
},
4262
}
4363

4464
for name, test := range tests {
4565
t.Run(name, func(t *testing.T) {
4666
assert := assert.New(t)
67+
require := require.New(t)
4768

4869
// Mocks.
4970
mr := &mmetrics.Recorder{}
50-
expHTTPReqProps := metrics.HTTPReqProperties{
51-
ID: test.expHandlerID,
52-
Service: test.expService,
53-
Method: test.expMethod,
54-
Code: test.expStatusCode,
55-
}
56-
expHTTPProps := metrics.HTTPProperties{
57-
ID: test.expHandlerID,
58-
Service: test.expService,
59-
}
60-
mr.On("ObserveHTTPRequestDuration", mock.Anything, expHTTPReqProps, mock.Anything).Once()
61-
mr.On("ObserveHTTPResponseSize", mock.Anything, expHTTPReqProps, mock.Anything).Once()
62-
mr.On("AddInflightRequests", mock.Anything, expHTTPProps, 1).Once()
63-
mr.On("AddInflightRequests", mock.Anything, expHTTPProps, -1).Once()
71+
test.mock(mr)
6472

65-
// Create our echo instance with the middleware.
73+
// Create our instance with the middleware.
6674
mdlw := middleware.New(middleware.Config{Recorder: mr})
6775
e := echo.New()
68-
e.POST("/test", getTestHandler(test.statusCode), echoMiddleware.Handler("", mdlw))
76+
req := test.req()
77+
e.Add(req.Method, req.URL.Path, test.handler(), echoMiddleware.Handler("", mdlw))
6978

7079
// Make the request.
7180
resp := httptest.NewRecorder()
72-
e.ServeHTTP(resp, test.req)
81+
e.ServeHTTP(resp, test.req())
7382

7483
// Check.
7584
mr.AssertExpectations(t)
76-
assert.Equal(test.statusCode, resp.Result().StatusCode)
85+
assert.Equal(test.expRespCode, resp.Result().StatusCode)
86+
gotBody, err := ioutil.ReadAll(resp.Result().Body)
87+
require.NoError(err)
88+
assert.Equal(test.expRespBody, string(gotBody))
7789
})
7890
}
7991
}

middleware/gin/gin.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
// Package gin is a helper package to get a gin compatible
2-
// handler/middleware from the standard net/http Middleware factory.
1+
// Package gin is a helper package to get a gin compatible middleware.
32
package gin
43

54
import (

middleware/gin/gin_test.go

+77-38
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,120 @@
11
package gin_test
22

33
import (
4+
"io/ioutil"
45
"net/http"
56
"net/http/httptest"
67
"testing"
78

89
"github.com/gin-gonic/gin"
910
"github.com/stretchr/testify/assert"
1011
"github.com/stretchr/testify/mock"
12+
"github.com/stretchr/testify/require"
1113

1214
mmetrics "github.com/slok/go-http-metrics/internal/mocks/metrics"
1315
"github.com/slok/go-http-metrics/metrics"
1416
"github.com/slok/go-http-metrics/middleware"
1517
ginmiddleware "github.com/slok/go-http-metrics/middleware/gin"
1618
)
1719

18-
func getTestHandler(statusCode int) gin.HandlerFunc {
19-
return func(c *gin.Context) {
20-
c.String(statusCode, "Hello world")
21-
}
22-
}
23-
2420
func TestMiddleware(t *testing.T) {
2521
tests := map[string]struct {
26-
handlerID string
27-
statusCode int
28-
req *http.Request
29-
config middleware.Config
30-
expHandlerID string
31-
expService string
32-
expMethod string
33-
expStatusCode string
22+
handlerID string
23+
config middleware.Config
24+
req func() *http.Request
25+
mock func(m *mmetrics.Recorder)
26+
handler func() gin.HandlerFunc
27+
expRespCode int
28+
expRespBody string
3429
}{
3530
"A default HTTP middleware should call the recorder to measure.": {
36-
statusCode: http.StatusAccepted,
37-
req: httptest.NewRequest(http.MethodPost, "/test", nil),
38-
expHandlerID: "/test",
39-
expMethod: http.MethodPost,
40-
expStatusCode: "202",
31+
req: func() *http.Request {
32+
return httptest.NewRequest(http.MethodPost, "/test", nil)
33+
},
34+
mock: func(m *mmetrics.Recorder) {
35+
expHTTPReqProps := metrics.HTTPReqProperties{
36+
ID: "/test",
37+
Service: "",
38+
Method: "POST",
39+
Code: "202",
40+
}
41+
m.On("ObserveHTTPRequestDuration", mock.Anything, expHTTPReqProps, mock.Anything).Once()
42+
m.On("ObserveHTTPResponseSize", mock.Anything, expHTTPReqProps, int64(5)).Once()
43+
44+
expHTTPProps := metrics.HTTPProperties{
45+
ID: "/test",
46+
Service: "",
47+
}
48+
m.On("AddInflightRequests", mock.Anything, expHTTPProps, 1).Once()
49+
m.On("AddInflightRequests", mock.Anything, expHTTPProps, -1).Once()
50+
},
51+
handler: func() gin.HandlerFunc {
52+
return func(c *gin.Context) {
53+
c.String(202, "test1")
54+
}
55+
},
56+
expRespCode: 202,
57+
expRespBody: "test1",
58+
},
59+
60+
"A default HTTP middleware using JSON should call the recorder to measure (Regression test: https://github.com/slok/go-http-metrics/issues/31).": {
61+
req: func() *http.Request {
62+
return httptest.NewRequest(http.MethodPost, "/test", nil)
63+
},
64+
mock: func(m *mmetrics.Recorder) {
65+
expHTTPReqProps := metrics.HTTPReqProperties{
66+
ID: "/test",
67+
Service: "",
68+
Method: "POST",
69+
Code: "202",
70+
}
71+
m.On("ObserveHTTPRequestDuration", mock.Anything, expHTTPReqProps, mock.Anything).Once()
72+
m.On("ObserveHTTPResponseSize", mock.Anything, expHTTPReqProps, int64(14)).Once()
73+
74+
expHTTPProps := metrics.HTTPProperties{
75+
ID: "/test",
76+
Service: "",
77+
}
78+
m.On("AddInflightRequests", mock.Anything, expHTTPProps, 1).Once()
79+
m.On("AddInflightRequests", mock.Anything, expHTTPProps, -1).Once()
80+
},
81+
handler: func() gin.HandlerFunc {
82+
return func(c *gin.Context) {
83+
c.JSON(202, map[string]string{"test": "one"})
84+
}
85+
},
86+
expRespCode: 202,
87+
expRespBody: `{"test":"one"}`,
4188
},
4289
}
4390

4491
for name, test := range tests {
4592
t.Run(name, func(t *testing.T) {
4693
assert := assert.New(t)
94+
require := require.New(t)
4795

4896
// Mocks.
4997
mr := &mmetrics.Recorder{}
50-
expHTTPReqProps := metrics.HTTPReqProperties{
51-
ID: test.expHandlerID,
52-
Service: test.expService,
53-
Method: test.expMethod,
54-
Code: test.expStatusCode,
55-
}
56-
expHTTPProps := metrics.HTTPProperties{
57-
ID: test.expHandlerID,
58-
Service: test.expService,
59-
}
60-
mr.On("ObserveHTTPRequestDuration", mock.Anything, expHTTPReqProps, mock.Anything).Once()
61-
mr.On("ObserveHTTPResponseSize", mock.Anything, expHTTPReqProps, mock.Anything).Once()
62-
mr.On("AddInflightRequests", mock.Anything, expHTTPProps, 1).Once()
63-
mr.On("AddInflightRequests", mock.Anything, expHTTPProps, -1).Once()
98+
test.mock(mr)
6499

65100
// Create our instance with the middleware.
66101
mdlw := middleware.New(middleware.Config{Recorder: mr})
67102
engine := gin.New()
68-
engine.POST("/test",
69-
ginmiddleware.Handler("", mdlw),
70-
getTestHandler(test.statusCode))
103+
req := test.req()
104+
engine.Handle(req.Method, req.URL.Path,
105+
ginmiddleware.Handler(test.handlerID, mdlw),
106+
test.handler())
71107

72108
// Make the request.
73109
resp := httptest.NewRecorder()
74-
engine.ServeHTTP(resp, test.req)
110+
engine.ServeHTTP(resp, req)
75111

76112
// Check.
77113
mr.AssertExpectations(t)
78-
assert.Equal(test.statusCode, resp.Result().StatusCode)
114+
assert.Equal(test.expRespCode, resp.Result().StatusCode)
115+
gotBody, err := ioutil.ReadAll(resp.Result().Body)
116+
require.NoError(err)
117+
assert.Equal(test.expRespBody, string(gotBody))
79118
})
80119
}
81120
}

middleware/gorestful/gorestful.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
// Package gorestful is a helper package to get a gorestful compatible
2-
// handler/middleware from the standard net/http Middleware factory.
1+
// Package gorestful is a helper package to get a gorestful compatible middleware.
32
package gorestful
43

54
import (

0 commit comments

Comments
 (0)