I need to test a set of gin handlers with dependencies. I have some successful unit tests up and running, mocking the gin context. I notice, however, that ShouldBindURI never works. The key passed to my repo mock is always empty.
I find this disturbing as it should be failing if it can't bind the key. I suspect this happens because it's unit tests, so I don't have a router telling it where to look for variables in the URL. Is there any way to tweak the gin context to fix this?
Simplified version of what I'm doing
type SomeHandler struct {
Repo ParticularRepoInterface
Queue Queuer
Timeout time.Duration
}
func NewHandler(repo DatabaseInterface, queue Queuer) *SomeHandler {
return &SomeHandler{
Repo: repo.ParticularRepo(),
Queue: queue,
Timeout: time.Second * 10,
}
func(ctrl *SomeHandler) List(c *gin.context) {
ctx, cancelContext := context.WithTimeout(c.Request.Context(), ctrl.Timeout)
defer cancelContext()
var key SomeKey
err := c.ShouldBindUri(&key)
if err != nil {
// handle BindError
}
thing, err := repo.List(ctx, key)
if err != nil {
// handle errors
}
c.JSON(http.StatusOk, thing)
}
// followed by the rest of CRUD.
Tests are unit tests, so I'm mocking the gin context. ParentID is the thing that gets bound in the key which is used to call List.
func TestThing(t *testing.T) {
t.Parallel()
assert := assert.New(t)
gin.SetMode(gin.TestMode)
now := time.Now().UTC()
filledThing := Thing{
ParentID: gofakeit.UUID(),
ThingID: gofakeit.UUID(),
Time: &now
}
nilThing := Thing{
ParentID: gofakeit.UUID(),
ThingID: gofakeit.UUID(),
Time: nil,
}
t.Run("Success", func(t *testing.T) {
t.Parallel()
var key SomeKey
parentID := gofakeit.UUID()
mockThingList := []*Thing{&nilThing, &filledThing}
mockQueue := NewMockQueue()
repo := new(mocks.MockThingRepo)
repo.On("List", mock.AnythingOfType("*context.valueCtx"), key).Return(mockThingList, nil)
handler := handlers.NewThing(mockRepo, mockQueue)
url := "/parents/" + parentID + "/things"
recorder := httptest.NewRecorder()
request, err := http.NewRequest(http.MethodGet, url, nil)
assert.NoError(err)
request.RequestURI = url
context, _ := gin.CreateTestContext(recorder)
context.Request = request
handler.List(context)
expectedResponse, err := json.Marshal(mockThingList)
assert.NoError(err)
// more assert tests
}
}