Тестирование
Что такое моки, зачем они нужны и где используются?
Mock-object (мок-объект или просто "мок") имеет наиболее близкое по смыслу слово — "заглушка".
Для тестов в проекте такие "заглушки" позволяют протестировать какую-либо структуру данных, не собирая для неё все зависимости.
Например:
type logger interface {
Log(level log.Level, keyvals ...interface{}) error
}
type sender interface {
Send(ctx context.Context, signal string) error
}
type Notifier struct {
sender sender
logger logger
}
func New(logger logger) *Notifier {
return &Notifier{logger: logger}
}
func (n *Notifier) NotifyAboutRain(ctx context.Context) error {
err := n.sender.Send(ctx, "It's raining now!")
if err != nil {
_ = n.logger.Log(log.LevelError, log.DefaultMessageKey, "failed to send notify about rain")
} else {
_ = n.logger.Log(log.LevelInfo, log.DefaultMessageKey, "notify about rain was successfully sent")
}
return err
}
В коде выше структура Notify зависит от интерфейсов sender и logger.
Чтобы проверить корректность метода NotifyAboutRain(ctx context.Context) error нет необходимости использовать
настоящую структуру для логирования, можно использовать заглушку:
type Logger struct {}
func (l *Logger) Log(log.Level, ...interface{}) error {
return nil
}
Такая заглушка позволит не беспокоиться о деталях работы логгера и проверить только необходимое.
В проекте используется библиотека github.com/matryer/moq для генерации простых моков, она позволяет по интерфейсу
создать минимальную структуру-заглушку, к которой можно выстраивать технические ожидания о вызове конкретных методов,
количестве и параметрах таких вызовов.
В проекте будут встречаться комментарии вида:
//go:generate moq -pkg mocks -skip-ensure -out mocks/tag_repository.go . tagRepository:TagRepository
Эти комментарии позволяют по команде make generate генерировать моки по указанным параметрам.
В примере выше указано два интерфейса — logger и sender, они являются зависимостями для структуры Notifier.
В проекте принято такие зависимости выносить в файл dependencies.go и использовать комментарии //go:generate moq
в таких файлах.
Пример использования моков в тестах — тесты в пакете internal/biz/cargo, проверяющие корректность интеграции.
Непосредственно сами тесты располагаются в файле internal/biz/cargo/integration_test.go