如何在Go表驱动测试中覆盖Mockery生成的Mock调用预期?
解决Mockery表驱动测试中Mock返回结果不更新的问题
问题原因
你的测试用例共享了同一个Mock对象,Mockery会保留所有通过On()设置的调用预期。后续子测试的On()是追加新的预期,而非替换原有预期。执行时Mock会按顺序匹配第一个符合条件的预期,所以第二个用例仍会返回第一个用例设置的结果。
解决方案
方案一:重置Mock的预期(推荐)
在每个子测试开头调用Reset()方法,清空之前的所有预期和调用记录,再设置当前用例的预期:
func (s *MyTestSuite) TestMySampleTest() { testCases := []struct { Name string mockedResult int expected int }{ { Name: "first case", mockedResult: 1, expected: 1, }, { Name: "second case", mockedResult: 2, expected: 2, }, } for _, tc := range testCases { s.Run(tc.Name, func() { // 重置Mock的所有预期与调用记录 s.someMock.Reset() // 设置当前测试用例的专属预期 s.someMock.On("SomeMethodCall", mock.Anything).Return(tc.mockedResult) result := s.SUT.SomeMethodThatCallsTheMockedOne() s.Equal(tc.expected, result) // 验证Mock是否按预期被调用(可选但建议添加) s.someMock.AssertExpectations(s.T()) }) } }
方案二:每个子测试重新创建Mock对象
如果不想复用Mock,可以在每个子测试中重新初始化Mock,并注入到被测试对象(SUT)中:
func (s *MyTestSuite) TestMySampleTest() { testCases := []struct { Name string mockedResult int expected int }{ { Name: "first case", mockedResult: 1, expected: 1, }, { Name: "second case", mockedResult: 2, expected: 2, }, } for _, tc := range testCases { s.Run(tc.Name, func() { // 新建Mock实例 mockObj := mock.NewMockSomeInterface(s.T()) mockObj.On("SomeMethodCall", mock.Anything).Return(tc.mockedResult) // 将新Mock注入SUT s.SUT = NewMyService(mockObj) result := s.SUT.SomeMethodThatCallsTheMockedOne() s.Equal(tc.expected, result) mockObj.AssertExpectations(s.T()) }) } }
内容的提问来源于stack exchange,提问作者beni0888
相关产品推荐
相关产品推荐

