You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go如何获取Mock函数调用参数?类似Jest/Mockito的参数捕获

Go Mock工具如何捕获函数调用参数(类似Jest/mock.calls或Mockito/ArgumentCaptor)

是的,Go生态中基于gomock的Mock工具(包括Mockery和Mockgen)完全支持参数捕获功能,对应你提到的Jest或Mockito的用法,下面针对你的场景给出具体实现:

场景回顾

你有一个Client.SubmitForm方法,内部调用httpClient.Do(),希望在测试中捕获传入该Mock方法的*http.Request参数,验证其构造是否符合预期。

实现方案

1. 直接捕获参数到变量(类似ArgumentCaptor)

使用gomock.Capture函数可以将调用时的参数保存到变量中,之后对变量进行断言:

t.Run("should call Do with valid post request", func(t *testing.T) {
    ctx := context.Background()
    ctx = context.WithValue(ctx, utils.CTXAuthTokenKey, "value")

    // 声明变量用于捕获请求参数
    var capturedReq *http.Request

    // 设置Mock期望时,用Capture捕获第三个参数
    mockHTTPClient.EXPECT().Do(
        ctx,
        "SubmitCall",
        gomock.Capture(func(req *http.Request) {
            capturedReq = req
        }),
    ).Return(&http.Response{
        StatusCode: http.StatusOK,
        Body:       io.NopCloser(bytes.NewReader([]byte("SUCCESS"))),
    }, nil)

    // 执行被测方法
    resp, err := client.SubmitForm(ctx)

    // 基础断言
    assert.NoError(t, err)
    assert.Equal(t, "SUCCESS", resp)

    // 验证捕获到的请求参数
    assert.Equal(t, http.MethodPost, capturedReq.Method)
    assert.Equal(t, "application/x-www-form-urlencoded", capturedReq.Header.Get("Content-Type"))
    
    // 验证URL
    parsedURL, _ := url.Parse(capturedReq.URL.String())
    assert.Equal(t, "api.mytestservice.com", parsedURL.Host)
    assert.Equal(t, "/submit", parsedURL.Path)
    
    // 可继续验证请求体、Authorization头等其他字段
})

2. 匹配时直接验证参数(无需保存)

如果不需要保存参数,只想在Mock匹配阶段直接验证参数合法性,可以用gomock.MatchedBy:

t.Run("should send correct request details", func(t *testing.T) {
    ctx := context.Background()
    ctx = context.WithValue(ctx, utils.CTXAuthTokenKey, "value")

    mockHTTPClient.EXPECT().Do(
        ctx,
        "SubmitCall",
        gomock.MatchedBy(func(req *http.Request) bool {
            // 在这里直接校验请求的各项属性
            return req.Method == http.MethodPost &&
                   req.Header.Get("Content-Type") == "application/x-www-form-urlencoded" &&
                   req.URL.Host == "api.mytestservice.com" &&
                   req.URL.Path == "/submit"
        }),
    ).Return(&http.Response{
        StatusCode: http.StatusOK,
        Body:       io.NopCloser(bytes.NewReader([]byte("SUCCESS"))),
    }, nil)

    resp, err := client.SubmitForm(ctx)
    assert.NoError(t, err)
    assert.Equal(t, "SUCCESS", resp)
})

多调用场景的参数捕获

如果Mock方法会被多次调用,想要捕获所有调用的参数,可以用切片存储:

var capturedReqs []*http.Request

mockHTTPClient.EXPECT().Do(
    gomock.Any(),
    gomock.Any(),
    gomock.Capture(func(req *http.Request) {
        capturedReqs = append(capturedReqs, req)
    }),
).Return(&http.Response{StatusCode: http.StatusOK, Body: io.NopCloser(bytes.NewReader([]byte("SUCCESS")))}, nil).AnyTimes()

// 执行被测逻辑后,遍历capturedReqs进行断言
for _, req := range capturedReqs {
    assert.Equal(t, http.MethodPost, req.Method)
    // 其他断言逻辑
}

内容的提问来源于stack exchange,提问作者Klaus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 14:55:22