Golang:如何模拟... interface {} arguents使用gomock

时间:2016-02-24 20:32:57

标签: go mocking printf gomock

我有一个Printer接口,它使用标准的go Printf函数签名:

type Printer interface {
    Printf(format string, tokens ...interface{})
}

我希望能够使用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

有谁知道更好的方法吗?

1 个答案:

答案 0 :(得分:1)

当前版本的gomock无法使用。也许你可以扩展它,并发送一个pull请求。要理解为什么它不可能,你必须查看为可变参数函数生成的模拟。

为此,让我们看看gomock的存储库中的示例,特别是./sample/mock_user/user.go./sample/mock_user/mock_user.go

Generated Mock

你会在 Index 界面中看到一个名为 Ellip 的函数,就像你的 Printf 函数一样:

type Index interface {
    // ...
    Ellip(fmt string, args ...interface{})
    // ...
}

现在,这是 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...)
}

注意到什么奇怪的?好吧,gomock正在创建一个接口片段 _s ,用第一个参数初始化。然后它将可变参数附加到接口切片 _s

因此,要明确的是,它不仅仅将可变参数 _param1 附加到切片。通过迭代将 _param1 中的每个变量附加到新切片。

这意味着不保留可变参数切片。它已经爆发了。