Тестовые двойники: имитации и заглушки
Интерфейсы для удобства тестирования и внедрение зависимостей
«Тестовые двойники: имитации и заглушки» — бесплатный урок Go Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Go Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Go Academy содержит 4 уроков всего.
Обзор тестовых заменителей
Тестовый заменитель подменяет реальную зависимость в тестах. Типы: заглушка (возвращает заранее заданные ответы), имитация (проверяет взаимодействия), шпион (записывает вызовы), поддельная реализация (работает в памяти).
Интерфейсы позволяют использовать тестовые заменители
Проектируйте функции так, чтобы они принимали интерфейсы, а не конкретные типы. В рабочем коде передавайте настоящую реализацию, а в тестах — тестовый заменитель.
type UserStore interface {
FindByID(id int) (*User, error)
}
func GetUser(store UserStore, id int) (*User, error) {
return store.FindByID(id)
}Ручная заглушка
Заглушка — это простая структура, реализующая интерфейс и возвращающая заранее настроенные значения:
type stubStore struct{ user *User; err error }
func (s *stubStore) FindByID(_ int) (*User, error) { return s.user, s.err }
// In test:
store := &stubStore{user: &User{Name: "Alice"}}
result, _ := GetUser(store, 1)Ручная имитация
Имитация записывает вызовы и проверяет их:
type mockStore struct {
called bool
gotID int
user *User
}
func (m *mockStore) FindByID(id int) (*User, error) {
m.called = true; m.gotID = id
return m.user, nil
}
// Assert: if !mock.called { t.Error(...) }testify/mock
Пакет testify/mock создаёт или позволяет писать объекты-имитации с ожиданиями вызовов и настройкой возвращаемых значений:
type MockStore struct { mock.Mock }
func (m *MockStore) FindByID(id int) (*User, error) {
args := m.Called(id)
return args.Get(0).(*User), args.Error(1)
}
// In test:
m := new(MockStore)
m.On("FindByID", 1).Return(&User{}, nil)
m.AssertExpectations(t)gomock
go.uber.org/mock/gomock (ранее golang/mock) создаёт имитации на основе интерфейсов. Используйте CLI mockgen для генерации и EXPECT() для задания ожиданий.
Поддельная реализация
Поддельная реализация — это рабочая реализация в памяти. Например, хранилище пользователей в памяти, сохраняющее пользователей в карте. Такие реализации сложнее писать, но они реалистичнее и менее хрупкие, чем имитации.
type fakeStore struct{ users map[int]*User }
func (f *fakeStore) FindByID(id int) (*User, error) {
u, ok := f.users[id]
if !ok { return nil, ErrNotFound }
return u, nil
}httptest для HTTP-клиентов
net/http/httptest предоставляет HTTP-сервер и средство записи для тестов, работающие внутри процесса, — это стандартная поддельная реализация для зависимостей на основе HTTP.
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(User{Name: "Alice"})
}))
defer ts.Close()Когда использовать каждый заменитель
Заглушка: простой фиксированный ответ. Имитация: проверка числа и аргументов вызовов. Поддельная реализация: сложное поведение. Избегайте чрезмерного использования имитаций — поддельные реализации и настоящие компоненты в интеграционных тестах надёжнее.
Как избежать хрупких тестов
Имитации, проверяющие точный порядок вызовов или значения аргументов, становятся хрупкими по мере развития реализации. По возможности предпочитайте заглушки с проверками результатов или поддельные реализации.
Выделение интерфейса
Выделяйте интерфейсы после определения поверхности конкретного типа, используемой вызывающим кодом (ISP). Go поддерживает неявное соответствие интерфейсам — изменять конкретный тип не требуется.
Быстрая проверка
В чём основное различие между заглушкой и имитацией?
Итоги: тестовые заменители
Основные положения:
- Проектируйте код на основе интерфейсов, чтобы использовать тестовые заменители
- Заглушка возвращает заранее заданные данные; имитация проверяет взаимодействия
- httptest используется для HTTP, а поддельные реализации в памяти — для хранилищ
- Избегайте чрезмерного использования имитаций — для сложного поведения предпочитайте поддельные реализации
Изучай Go с ИИ-репетитором — бесплатно
Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.
- Курсы
- 51
- Уроки
- 203
Часто задаваемые вопросы
Урок «Тестовые двойники: имитации и заглушки» бесплатный?
Да — полный текст урока «Тестовые двойники: имитации и заглушки» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Go Academy, подпишись на CoddyKit PRO. Курс Go Academy содержит 4 уроков всего.
Чему я научусь в уроке «Тестовые двойники: имитации и заглушки»?
Интерфейсы для удобства тестирования и внедрение зависимостей Ты практикуешь Go Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Go Academy?
Предыдущий опыт не требуется. Go Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Тестовые двойники: имитации и заглушки»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Go Academy?
Да. Каждый урок Go Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Написание модульных тестов с testing
- Тесты на основе таблиц
- Тестовые двойники: имитации и заглушки
- Покрытие тестами и testify