Замена зависимостей в коде на моки может упростить написание тестов и ускорить выполнение. Однако, помимо прочих проблем, моки могут привести к тому, что тесты будут малоэффективны для выявления багов.
Надежность или достоверность (fidelity) теста означает, насколько поведение теста похоже на поведение production-кода. Тест с более высокой надежностью дает больше уверенности, что тестируемый код будет работать правильно.
Указывая зависимость для использования в тесте, отдавайте предпочтение варианту с наивысшей возможной надежностью. Более подробная информация содержится в главе Test Doubles книги Software Engineering at Google.
- Старайтесь использовать реальную имплементацию. Это обеспечит наибольшую достоверность, поскольку в тесте будет выполняться код из имплементации. При использовании реальной имплементации возможны компромиссы: она может быть медленной, не очень детерминированной или сложной для инстанцирования (например, подключается к внешнему серверу). Решайте сами, применима ли реальная имплементация в каждом случае.
- Используйте фейк, если не можете использовать реальную имплементацию. Фейк — облегченная имплементация API, которая ведет себя аналогично реальной, например, in-memory база данных. Фейк обеспечивает высокую надежность тестирования, но требует некоторых усилий для написания и поддержки; например, его тоже нужно протестировать, чтобы убедиться, что его поведение соответствует поведению реальной имплементации. Поэтому, как правило, владелец реальной имплементации создает и поддерживает ее фейк.
- Используйте мок, если не можете использовать реальную имплементацию или фейк. Мок снижает надежность теста, поскольку он не выполняет имплементацию зависимости; его поведение задается в тесте (техника, известная как stubbing), поэтому это поведение может отличаться от поведения реальной имплементации. Моки обеспечивают базовый уровень уверенности в том, что тестируемый код работает правильно, и особенно полезны при тестировании пути в кода, который трудно вызвать (например, условие ошибки по таймауту).
(Примечание: Хотя «моки» — это объекты, созданные с помощью таких фреймворков, как Mockito или unittest.mock, те же проблемы возникнут, если вы вручную создадите собственную имплементацию в тесте).
Тест с низкой степенью надежности: Зависимости заменяются моками. Старайтесь избегать этого. | Тест с высокой надежностью: Зависимости используют реальные имплементации или фейки. Предпочитаемый вариант. |
@Mock OrderValidator validator; @Mock PaymentProcessor processor; … ShoppingCart cart = new ShoppingCart( validator, processor); | OrderValidator validator = createValidator(); PaymentProcessor processor = new FakeProcessor(); … ShoppingCart cart = new ShoppingCart( validator, processor); |
Стремитесь к такой надежности, которой можно достичь, не увеличивая объем теста. В Google тесты классифицируются по размеру. Большинство тестов должны быть небольшими: они должны выполняться в рамках одного процесса и не должны ожидать ответа системы или событие за пределами своего процесса. Увеличение надежности небольшого теста часто является хорошим вариантом, если тест остается в рамках этих ограничений. Хороший тестовый набор у нас также включает средние и большие тесты c высокой надежностью — поскольку там могут быть «тяжелые» зависимости, которые нецелесообразно использовать в маленьких тестах; например, зависимости, увеличивающие время выполнения или вызывающие другие процессы.
Моки, стабы, пустышки, шпионы и фейки — полный гайд