Home >Backend Development >Golang >How to Effectively Unit Test Go Gin Handler Functions with Data Binding and Service Dependencies?
How to Unit Test a Go Gin Handler Function with Request Data Binding
In unit testing Gin handler functions, properly initializing and setting the request body and query parameters is crucial. Let's delve into how to effectively test c.BindQuery.
In the provided test code, c.BindQuery is not working because the HTTP request is not initialized with any query parameters. To mock c.BindQuery, you need to create a test request and set its URL and URL.RawQuery accordingly. Here's an improved version:
func mockGin() (*gin.Context, *httptest.ResponseRecorder) { w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) // Create a test request with query parameters req := &http.Request{ URL: &url.URL{}, Header: make(http.Header), } testQuery := weldprogs.QueryParam{/* init fields */} q := req.URL.Query() for _, s := range testQuery.Basematgroup_id { q.Add("basematgroup_id", s) } req.URL.RawQuery = q.Encode() c.Request = req return c, w }
Once you've mocked the query binding, you can test c.BindQuery in your handler function GetMaterialByFilter.
Testing Service Dependencies
Your handler function also makes a call to the service services.WeldprogService.GetMaterialByFilter. To make this call testable, the service should be an interface that can be injected as a dependency of your handler.
Here's how to do this:
// Define an interface for your service type WeldprogService interface { GetMaterialByFilter(query *weldprogs.QueryParam) ([]weldprogs.Material, error) } // Inject the service into your handler as a context value func GetMaterialByFilter(c *gin.Context) { //... weldprogService := mustGetService(c) materialByFilter, getErr := weldprogService.GetMaterialByFilter(&queryParam) // ... } func mustGetService(c *gin.Context) WeldprogService { svc, exists := c.Get("svc_context_key") if !exists { panic("service was not set") } return svc.(WeldprogService) }
Now, you can mock the service in your unit tests and control its behavior:
type mockSvc struct { } // Implement the WeldprogService interface on mockSvc func TestGetMaterialByFilter(t *testing.T) { w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) // Set the mock service into the test context c.Set("svc_context_key", &mockSvc{}) GetMaterialByFilter(c) // ... }
The above is the detailed content of How to Effectively Unit Test Go Gin Handler Functions with Data Binding and Service Dependencies?. For more information, please follow other related articles on the PHP Chinese website!