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

Testify mock已配期望 不同参数两次调用报意外方法调用错误

问题描述

业务用例逻辑会分两次调用被mock的Repository层GetByID方法,两次调用传入的参数不一致。初始编写的测试代码如下:

func TestInitUserSubscription(t *testing.T) {
    aRepository := &aRepositoryMock{}

    // 原注释:期望该方法被调用两次
    aRepository.On("GetByID", data.ID).Return(*data, nil)

    bUseCase := New(
        aRepository,
    )

    result, err := bUseCase.Init(data.Name)
}

运行测试时报错如下:

mock: Unexpected Method Call
-----------------------------

GetByID(uint64)
                0: 0x0

The closest call I have is:

GetByID(uint64)
                0: 0x1


Diff: 0: FAIL:  (uint64=0) != (uint64=1) [recovered]
        panic:

mock: Unexpected Method Call
-----------------------------

GetByID(uint64)
                0: 0x0

The closest call I have is:

GetByID(uint64)
                0: 0x1


Diff: 0: FAIL:  (uint64=0) != (uint64=1)

尝试添加.Twice()配置调用次数后问题仍未解决。

故障原因

testify mock组件默认对方法调用做严格参数匹配:

  • 原有代码只注册了参数为data.ID(对应报错里的0x1,即uint64值为1)的调用期望
  • 第二次调用传入的参数值为0(对应报错里的0x0),没有匹配到对应的注册期望
  • .Twice()的作用是标记「相同参数、相同返回的调用需要发生两次」,无法适配两次调用参数不同的场景,因此无法解决问题。
解决方案

根据业务测试需求三选一即可:

  • 明确两次调用的参数和预期返回值:分别为两次不同参数的调用注册独立的On期望
    func TestInitUserSubscription(t *testing.T) {
        aRepository := &aRepositoryMock{}
    
        // 注册第一次调用:参数为1时返回data
        aRepository.On("GetByID", uint64(1)).Return(*data, nil)
        // 注册第二次调用:参数为0时返回对应预期值(按业务逻辑调整返回内容,比如空实体、未找到错误等)
        var emptyData YourDataType
        aRepository.On("GetByID", uint64(0)).Return(emptyData, nil)
    
        bUseCase := New(aRepository)
        result, err := bUseCase.Init(data.Name)
    
        // 校验所有注册的期望都被调用
        aRepository.AssertExpectations(t)
    }
    
  • 不关心传入参数的具体值,所有调用都返回固定结果:使用mock.Anything作为参数匹配符,搭配.Twice()标记调用次数
    import "github.com/stretchr/testify/mock"
    
    // mock.Anything会匹配任意类型、任意值的参数
    aRepository.On("GetByID", mock.Anything).Return(*data, nil).Twice()
    
  • 需要自定义参数校验规则:使用mock.MatchedBy传入自定义匹配函数
    import "github.com/stretchr/testify/mock"
    
    // 例子:匹配所有大于等于0的uint64类型ID
    aRepository.On("GetByID", mock.MatchedBy(func(id uint64) bool {
        return id >= 0
    })).Return(*data, nil).Twice()
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 04:21:24