Голанг: как издеваться над интерфейсом {}, используя аргументы 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
Кто-нибудь знает лучший способ сделать это?
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{})
// ...
}
Теперь вот как выглядит смоделированная функция для 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 добавляется к новому слайсу путем его итерации.
Это означает, что срез переменных параметров не сохраняется. Это вспыхнуло.
По состоянию на 1 октября 2017 г.
gomock.Any()
корректно работает для переменных аргументов: https://github.com/golang/mock/pull/101