Удобные моки в Go: как упростить unit-тестирование
Практическое руководство по использованию мок-объектов в Go с помощью mockery и организации тестов через вспомогательные контейнеры.
Unit-тестирование - неотъемлемая часть разработки качественного программного обеспечения. Особенно это актуально при работе с бизнес-логикой, где важно изолировать тестируемый компонент от его зависимостей (например, базы данных, внешних API и т.д.).
В Go для этой цели часто используют моки - заглушки, имитирующие поведение зависимостей. Когда проект построен по принципам слоёной архитектуры и инверсии зависимостей (Dependency Inversion Principle из SOLID), интерфейсы уже есть «из коробки», и создание моков становится естественным шагом.
В этой статье мы рассмотрим, как сделать работу с моками удобнее, используя инструмент mockery и небольшую вспомогательную структуру для организации тестов.
В примерах используется
mockeryверсии 2.x. Начиная с версии 3, синтаксисgo:generateнемного изменился - об этом ниже.
Пример бизнес-логики
Рассмотрим упрощённый сервис регистрации пользователей:
| |
В примере намеренно упрощена реализация. В реальном проекте стоит вынести ошибки в отдельный пакет и добавить проверку на дубликаты. Однако для демонстрации принципа этого достаточно.
Генерация моков с помощью mockery
Для автоматической генерации моков используем mockery . Для версий до 3.0 достаточно добавить директиву go:generate:
| |
После запуска go generate ./... будет создан файл с моком, например, в папке mocks/.
Начиная с
mockery v3, рекомендуется использовать конфигурационный файл.mockery.yamlи вызыватьmockeryнапрямую, а не черезgo:generate. Подробнее в официальной документации.
Альтернативные инструменты, такие как gomock или minimock, предлагают схожий подход - генерация моков на основе интерфейсов.
Организация тестов через вспомогательный контейнер
Чтобы избежать дублирования кода инициализации моков в каждом тесте, можно завести небольшую вспомогательную структуру:
| |
Такой подход особенно удобен, когда зависимостей становится больше: достаточно обновить testMocks и newTestMocks, и все тесты получат актуальные заглушки.
Написание чистых и читаемых тестов
Теперь тесты становятся лаконичными и сфокусированными на проверяемом поведении:
| |
Заключение
Использование вспомогательных структур вроде testMocks и генераторов моков (например, mockery) позволяет писать unit-тесты в Go удобнее. Такой подход масштабируется по мере роста проекта и делает тесты чище, читаемее и проще в поддержке.
Если ты только начинаешь писать тесты - не бойся начинать с простого. Даже базовая изоляция зависимостей через интерфейсы и моки уже даёт огромную пользу.
📎 Источники: