You can use Unset to remove the expectations on a given call. This is useful if you have a shared mock due to reasons like expensive setup or dependent tests.
main_test.go
func TestDownloadVideo_ResetBetweenSubtests(t *testing.T) {
ctx := context.Background()
mockProc := servicemock.NewProcessor(t)
mockLog := servicemock.NewLogger(t)
mockLog.On("Errorf", mock.Anything, mock.Anything).Return().Maybe()
tests := []struct {
name string
videoID string
}{
{name: "first", videoID: "vid-1"},
{name: "second", videoID: "vid-2"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Reuse the same mock across subtests (assume expensive setup),
// then remove only this expectation so the next subtest starts clean.
call := mockProc.On("Download", mock.Anything, tt.videoID).Return([]byte("raw"), nil).Once()
defer call.Unset()
got, err := DownloadVideo(ctx, mockProc, mockLog, tt.videoID)
require.NoError(t, err)
require.Equal(t, []byte("raw"), got)
mockProc.AssertExpectations(t)
})
}
}
main.go
//go:generate mockery --name=Processor --dir=. --output=./mocks --outpkg=servicemock --case=snake
//go:generate mockery --name=Logger --dir=. --output=./mocks --outpkg=servicemock --case=snake
// ...
type Processor interface {
Download(ctx context.Context, videoID string) ([]byte, error)
}
type Logger interface {
Errorf(format string, args ...any)
}
func DownloadVideo(ctx context.Context, p Processor, log Logger, videoID string) ([]byte, error) {
if videoID == "" {
err := fmt.Errorf("videoID must be non-empty")
log.Errorf("download failed: %v", err)
return nil, err
}
data, err := p.Download(ctx, videoID)
if err != nil {
log.Errorf("download failed: %v", err)
return nil, err
}
return data, nil
}
Note: mocked object results are omitted.