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
相关产品推荐
相关产品推荐

