Ответ
Mock-объекты (моки) — это "поддельные" реализации зависимостей, которые используются в тестах для имитации поведения реальных объектов. Они позволяют изолировать тестируемый компонент от его внешних зависимостей (например, базы данных, внешнего API, файловой системы).
Ключевые цели использования моков:
- Изоляция: Тестировать один компонент, не затрагивая другие.
- Контроль: Управлять поведением зависимости (например, заставить метод вернуть ошибку или определенные данные).
- Проверка взаимодействий: Убедиться, что тестируемый код вызывает нужные методы зависимости с правильными параметрами.
Способы создания моков в Go
В Go мокирование тесно связано с использованием интерфейсов. Есть два основных подхода:
1. Ручная реализация
Вы вручную создаете структуру, которая реализует нужный интерфейс. Этот подход хорош для простых случаев.
// Интерфейс нашей зависимости
type DBLayer interface {
GetUser(id int) (*User, error)
}
// Mock-структура, реализующая интерфейс
type MockDB struct {
GetUserFunc func(id int) (*User, error)
}
// Реализация метода интерфейса
func (m *MockDB) GetUser(id int) (*User, error) {
// Вызываем функцию, которую мы подставим в тесте
return m.GetUserFunc(id)
}
// Пример теста
func TestService_GetUser(t *testing.T) {
// Создаем и настраиваем мок
mockDB := &MockDB{
GetUserFunc: func(id int) (*User, error) {
if id == 1 {
return &User{ID: id, Name: "Alice"}, nil
}
return nil, errors.New("user not found")
},
}
service := NewService(mockDB)
user, err := service.GetUser(1)
// Проверки...
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
if user.Name != "Alice" {
t.Errorf("Expected user name 'Alice', got '%s'", user.Name)
}
}
2. Использование кодогенераторов (предпочтительный способ)
Для сложных интерфейсов ручное создание моков утомительно. Библиотеки, такие как gomock
(с утилитой mockgen
) и testify/mock
, автоматизируют этот процесс.
gomock
/mockgen
: Стандарт де-факто от Google. Генерирует полнофункциональные моки на основе интерфейсов. Позволяет гибко настраивать ожидания (вызовы, параметры, возвращаемые значения).testify/mock
: Популярная библиотека, которая также позволяет создавать моки, но требует немного больше ручного кода для их настройки по сравнению сgomock
.