首页 >后端开发 >Golang >如何模拟 Gin 的 `c.BindQuery` 进行有效的单元测试?

如何模拟 Gin 的 `c.BindQuery` 进行有效的单元测试?

Barbara Streisand
Barbara Streisand原创
2024-12-30 15:43:14512浏览

How to Mock Gin's `c.BindQuery` for Effective Unit Testing?

模拟 Gin 处理程序 c.BindQuery 进行单元测试

问题

调用 c.BindQuery 时,Gin 处理程序函数 GetMaterialByFilter 的单元测试失败。如何通过模拟函数来解决这个问题?

概述

问题源于测试过程中缺少实际的 HTTP 请求。要执行基于 HTTP 的操作,必须初始化请求并将其设置到 Gin 上下文。具体来说,对于 c.BindQuery,正确初始化请求的 URL 和 URL.RawQuery 至关重要。

模拟实现

要模拟 c.BindQuery,请按照以下步骤操作:

  1. 初始化 *gin.Context 和 *httptest.ResponseRecorder。
  2. 创建一个*http.Request 并根据需要设置其 URL 和 Header。
  3. 初始化请求查询 (weldprogs.QueryParam) 并将其编码到 URL.RawQuery。
  4. 将请求设置到 Gin 上下文使用 c.Request = req.
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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn