I have a Printer
interface that uses the standard go Printf
function signature:
type Printer interface {
Printf(format string, tokens ...interface{})
}
I would like to be able to mock this interface using gomock, but I'm not sure how setup the tokens ...interface{}
argument properly.
I expected that Printf(gomock.Any(), gomock.Any())
would cover all potential cases (since tokens
compiles to []interface{}
), but it appears you need to setup an explicit call for N number of tokens:
// no tokens
mockPrinter.EXPECT().
Printf(gomock.Any()).
AnyTimes()
// 1 token
mockPrinter.EXPECT().
Printf(gomock.Any(), gomock.Any()).
AnyTimes()
// 2 tokens
mockPrinter.EXPECT().
Printf(gomock.Any(), gomock.Any(), gomock.Any()).
AnyTimes()
// ... up to N tokens
Does anyone know of a better way to do this?
Not possible with the current version of gomock. Maybe you can extend it, and send a pull request in. To understand why it's not possible, you have to look at the mock generated for variadic functions.
To do that, let's look at the examples in gomock's repository, specifically ./sample/mock_user/user.go and ./sample/mock_user/mock_user.go.
Generated Mock
You'll see a function in the Index inteface called Ellip, which is like your Printf function:
Now, here's what the mocked function looks like for Ellip:
Notice anything odd? Well, gomock is creating a slice of interfaces, _s, initialized with the first parameter. Then it appends the variadic parameters to that slice of interfaces, _s.
So, to be clear, it doesn't just append the variadic parameter, _param1, to the slice. Each individual variadic from _param1 is appended to the new slice, by iterating through it.
This means that the slice of variadic parameters is not preserved. It's broken out.