Zac*_*ack 5 printf mocking go gomock
我有一个Printer使用标准 goPrintf函数签名的接口:
type Printer interface {
Printf(format string, tokens ...interface{})
}
Run Code Online (Sandbox Code Playgroud)
我希望能够使用gomock模拟此接口,但我不确定如何tokens ...interface{}正确设置参数。
我预计这Printf(gomock.Any(), gomock.Any())将涵盖所有潜在情况(因为tokens编译为[]interface{}),但似乎您需要为 N 个令牌设置显式调用:
// 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
Run Code Online (Sandbox Code Playgroud)
有谁知道更好的方法来做到这一点?
小智 2
当前版本的 gomock 不可能。也许您可以扩展它,并发送拉取请求。要理解为什么这是不可能的,您必须查看为可变参数函数生成的模拟。
为此,让我们看一下 gomock 存储库中的示例,特别是./sample/mock_user/user.go和./sample/mock_user/mock_user.go。
您将在Index界面中看到一个名为Ellip的函数,它类似于Printf函数:
type Index interface {
// ...
Ellip(fmt string, args ...interface{})
// ...
}
Run Code Online (Sandbox Code Playgroud)
现在,这是Ellip的模拟函数的样子:
func (_m *MockIndex) Ellip(_param0 string, _param1 ...interface{}) {
_s := []interface{}{_param0}
for _, _x := range _param1 {
_s = append(_s, _x)
}
_m.ctrl.Call(_m, "Ellip", _s...)
}
Run Code Online (Sandbox Code Playgroud)
注意到有什么奇怪的吗?好吧, gomock 正在创建一个接口切片_s ,并使用第一个参数进行初始化。然后它将可变参数附加到该接口片段_s。
因此,需要明确的是,它不仅仅将可变参数_param1附加到切片。通过迭代,将_param1中的每个单独的变量附加到新切片。
这意味着可变参数切片不会被保留。它坏了。