Ответ
В Go существует два основных подхода к мокированию зависимостей в тестах, и для каждого есть свои популярные инструменты.
1. Кодогенерация (Code Generation)
Этот подход заключается в автоматической генерации мок-объектов на основе интерфейсов. Это предпочтительный способ для сложных интерфейсов, так как он обеспечивает строгую типизацию и избавляет от рутины.
-
golang/mock
(gomock
)- Описание: Официальная библиотека от Google. Использует утилиту
mockgen
для генерации моков из интерфейсов. Очень мощная и гибкая. - Плюсы: Строгая проверка типов, интеграция с
testing.T
, выразительный синтаксис для описания ожиданий (EXPECT()
).
- Описание: Официальная библиотека от Google. Использует утилиту
-
vektra/mockery
- Описание: Популярная альтернатива
gomock
. Также генерирует моки на основе интерфейсов, но многие находят её проще в настройке и использовании. - Плюсы: Простая установка и конфигурация, генерирует код, который легко читать.
- Описание: Популярная альтернатива
2. Ручное мокирование с использованием библиотек
В этом случае вы самостоятельно создаете структуру-мок, которая реализует нужный интерфейс, а библиотека помогает управлять ожиданиями и проверками.
-
testify/mock
- Описание: Самая популярная библиотека для этого подхода. Является частью пакета
testify
. Не требует кодогенерации. - Плюсы: Простота, не нужен шаг кодогенерации, легко начать использовать.
-
Пример:
import ( "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) // Мок-структура, реализующая интерфейс type MyMockedObject struct { mock.Mock } // Реализация метода интерфейса func (m *MyMockedObject) DoSomething(input int) (bool, error) { // .Called() регистрирует вызов и его аргументы args := m.Called(input) // .Get() позволяет вернуть заранее определенные значения return args.Bool(0), args.Error(1) } func TestSomething(t *testing.T) { // Создаем экземпляр мока testObj := new(MyMockedObject) // Настраиваем ожидание: при вызове DoSomething(123) // вернуть true и nil testObj.On("DoSomething", 123).Return(true, nil) // ... здесь код, который вызывает testObj.DoSomething(123) ... // Проверяем, что все ожидаемые вызовы были совершены testObj.AssertExpectations(t) }
- Описание: Самая популярная библиотека для этого подхода. Является частью пакета
Специализированные библиотеки
h2non/gock
илиjarcoal/httpmock
: Используются для мокирования HTTP-клиентов и ответов на внешние запросы. Это незаменимо при тестировании кода, который взаимодействует с внешними API.
Вывод:
- Для небольших проектов или простых интерфейсов отлично подходит
testify/mock
. - Для крупных проектов с множеством сложных интерфейсов предпочтительнее использовать кодогенерацию с помощью
gomock
илиmockery
, так как это повышает надежность тестов.