Писали ли интеграционные тесты или моки для сервисов с Dependency Injection
Что проверяют
Понимаете ли вы, что внедрение зависимостей в Go это обычная передача интерфейса в конструктор, и умеете ли подменять её без лишней машинерии. Заодно видно, где вы проводите границу между моком и настоящей зависимостью.
Как отвечать
Опишите схему: конструктор принимает узкий интерфейс, объявленный на стороне потребителя, а не рядом с реализацией. В тесте туда передаётся своя структура.
type accountStore interface {
Balance(ctx context.Context, id int64) (int64, error)
}
type stubStore struct{ balance int64 }
func (s stubStore) Balance(context.Context, int64) (int64, error) {
return s.balance, nil
}Дальше про инструменты: ручной стаб на пару методов, генерация моков, когда нужен контроль вызовов и их порядка, библиотека утверждений по вкусу команды. Интеграционные тесты поднимают настоящую базу контейнером, живут под отдельным тегом сборки или флагом, убирают за собой через t.Cleanup, а внешний HTTP заменяется локальным тестовым сервером. Табличная форма теста здесь привычна и читается лучше набора отдельных функций.
Где спотыкаются
Мокают всё подряд. Тест начинает проверять, что код вызвал то, что он вызвал, и краснеет на любом рефакторинге, хотя поведение не поменялось. Слой работы с базой разумнее проверять на настоящей базе.
Объявляют интерфейс на полтора десятка методов рядом с реализацией ради удобной генерации мока. В Go интерфейс принадлежит вызывающему коду и содержит ровно то, что нужно именно ему, иначе поддержка моков становится отдельной работой.
Кладут интеграционные тесты в общий прогон. После этого прогон всех пакетов без поднятой базы красный у всех, и его перестают запускать локально. Тег сборки или проверка флага стоят одной строки.