Как стать автором
Обновить

Когда использовать mocks в юнит-тестировании

Время на прочтение13 мин
Количество просмотров72K
Всего голосов 16: ↑16 и ↓0+16
Комментарии6

Комментарии 6

Отличное упорядочивание. Разве что ещё стоит добавить "нестабильные зависимости". Это рандом, время, внешние сервисы и тп. Их стоит мокать даже если они управляемые.

Спасибо за статью.

Обычно я в команде главный противник (чрезмерных) моков, потому что тесты слишком раздутые получаются и хрупкие. К тому же обычно никто не тестирует взаимодействие реальных компонентов, только их в отдельности.

В статье чуть лучше описано обоснование для моих аргументов

Шикарная статья, такой давно не хватало.

Тоже предпочитаю избегать использования моков, но иногда приходится мокать внешние контролируемые зависимости (БД для серверных тестов, api для ui тестов), поскольку иначе может сильно замедляться выполнение тестов, поскольку нет возможности параллельно выполнять тесты без их влияния друг на друга.

"внутрипроцессорные зависимости"/"внепроцессорные зависимости" - это "lost in translation" (в русском варианте этот фильм назвали "трудности перевода", что еще раз подтвердило проблему из оригинального фильма), или устоявшаяся терминология?

Пол статьи убили на то, чтобы описать разницу моков и стабов (сомнительное конечно разделение при том что и то и другое моки) и только к концу главы пришли к примеру CQS, который все расставил бы по полочкам с самого начала. Воды, воды, еще больше воды!!!

Как по мне моки нужны только для ситуаций когда в момет выполнения тестов у нас нет нужной службы, либо она не нужна для теста (бд, брокер сообщение, почтовый сервер и т.д.). В остальном если строить тесты по принципу черного ящика (когда нам без разницы что внутри), то хрупкость тестов ооочень сложно достичь.

Примеры из статьи же:

  1. Creating_a_report - зачем нам проверять сколько раз вызывался "GetNumberOfUsers" ? Нам важем результат, нам без разницы сколько раз вызывалась функция.

  2. Purchase_fails_when_not_enough_inventory - зачем нам проверять что не удалялось именно 5 штук шампуней? Нам нужно убедиться, что вообще ничего не удалялось, т.е. метод RemoveInventory не вызывался (опять таки это зависит от заложенной логики)

Т.е. если подойти с другого бока к тестам нужно относиться (и стараться достичь этого) как к функциональному программированию: при отправке одних и тех же аругментов, мы должны получать ровно тот же результат, и как раз это должны обеспечивать моки (сохранение одинакого состояния от теста к тесту).

Если касаться же подхода проектирования, то на CQS очень хорошо ложатся тесты: каждой команде/запросу все необходимые сервисы/сущности передаются в конструкторе (если конечно передаются и в целом на проекте используется DI) и тестируется ровно один метод (execute/query). Таким образом при написании тестов мы сами контролируем какие зависимости отправлять, мы точно знаем, что должно происходить при выполнении команды/запроса, и нам абсолютно не важно* что происходит внутри, нам важно выполнение команды и один из ее возможных вариантов завершения.

А дополнительные размышления по поводу "хм, это мок или стаб?" только тормозят сам процесс написания теста. Конечно, такое разделение нужно для того, чтобы быстро понять надо ли проверять или нет, НО зачем вводить дополнительные условия (да к тому же еще и 5 вариантов моков), если это все должна диктовать бизнес-логика приложения? Если нам важно с точки зрения выполнения конкретной задачи выполняется тот или иной метод мока - то нужно это проверить. Если нам не важно и это никак не влияет на результат задачи - то нам и надо это проверять. И не нужно вводить дополнительные термины и строить теорию на ровном месте, где она абсолютно не нужно.

*По поводу "абсолютно не важно" небольшая ремарка: если в рамках бизнес-логики должно отправляться письмо клиенту, то это нам конечно нужно проверить (замокать EmailService), но нам точно неважно вызывался ли, и сколько раз, какой-то вспомогательный сервис, который никак не влияет на результат выполнения команды. Например, мы тестируем создание заказа на недостаточное количество товара, нам абсолютно без разницы запрашивалось ли количество товара на складе и сколько раз, нам важно, что заказ не будет создан по причине недостаточности товара (кинет соответствующее исключение или вернет ошибку).

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации