Голанг: как издеваться над интерфейсом {}, используя аргументы 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

Другие вопросы по тегам