调用 c.BindQuery 时,Gin 处理程序函数 GetMaterialByFilter 的单元测试失败。如何通过模拟函数来解决这个问题?
问题源于测试过程中缺少实际的 HTTP 请求。要执行基于 HTTP 的操作,必须初始化请求并将其设置到 Gin 上下文。具体来说,对于 c.BindQuery,正确初始化请求的 URL 和 URL.RawQuery 至关重要。
要模拟 c.BindQuery,请按照以下步骤操作:
func mockGin() (*gin.Context, *httptest.ResponseRecorder) { w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) 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 }
此外,services.WeldprogService.GetMaterialByFilter(&queryParam) 调用在当前形式下不可测试。它应该是一个接口,并作为处理程序的依赖项注入。
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) }
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) // ... }
通过组合这些技术,您可以可以有效地模拟 c.BindQuery 和外部依赖项,从而允许对 Gin 处理程序函数进行全面的单元测试。
以上是如何模拟 Gin 的 `c.BindQuery` 进行有效的单元测试?的详细内容。更多信息请关注PHP中文网其他相关文章!