To test operations that involve the HTTP request, you have to actually initialize an *http.Request
and set it to the Gin context. To specifically test c.BindQuery
it’s enough to properly initialize the request’s URL
and URL.RawQuery
:
func mockGin() (*gin.Context, *httptest.ResponseRecorder) {
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
// test request, must instantiate a request first
req := &http.Request{
URL: &url.URL{},
Header: make(http.Header), // if you need to test headers
}
// example: req.Header.Add("Accept", "application/json")
// request query
testQuery := weldprogs.QueryParam{/* init fields */}
q := req.URL.Query()
for _, s := range testQuery.Basematgroup_id {
q.Add("basematgroup_id", s)
}
// ... repeat for other fields as needed
// must set this, since under the hood c.BindQuery calls
// `req.URL.Query()`, which calls `ParseQuery(u.RawQuery)`
req.URL.RawQuery = q.Encode()
// finally set the request to the gin context
c.Request = req
return c, w
}
If you need to mock JSON binding, see this answer.
The service call services.WeldprogService.GetMaterialByFilter(&queryParam)
can’t be tested as is. To be testable it has to be (ideally) an interface and somehow injected as dependency of your handler.
Assuming that it is already an interface, to make it injectable, you either require it as an handler argument — but this forces you to change the signature of the handler —, or you set it as a Gin context value:
func GetMaterialByFilter(c *gin.Context) {
//...
weldprogService := mustGetService(c)
materialByFilter, getErr := weldprogService.GetMaterialByFilter(&queryParam)
// ...
}
func mustGetService(c *gin.Context) services.WeldprogService {
svc, exists := c.Get("svc_context_key")
if !exists {
panic("service was not set")
}
return svc.(services.WeldprogService)
}
Then you can mock it in your unit tests:
type mockSvc struct {
}
// have 'mockSvc' implement the interface
func TestGetMaterialByFilter(t *testing.T) {
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
// now you can set mockSvc into the test context
c.Set("svc_context_key", &mockSvc{})
GetMaterialByFilter(c)
// ...
}