Mocking
Тема дорожной карты · Node.js
Моки в тестировании Node.js заменяют реальные реализации модулей, функций или сервисов управляемыми заместителями, возвращающими предсказуемые значения, что позволяет юнит-тестам серверного кода работать быстро и детерминированно без реальных баз данных, HTTP-вызовов или операций с файловой системой. Фреймворк тестирования jest предоставляет первоклассную поддержку моков: jest.mock('module-name') автоматически мокирует целый npm-пакет или локальный модуль, jest.spyOn(object, 'method') перехватывает конкретные вызовы методов, опционально сохраняя оригинальную реализацию, а jest.fn() создаёт независимые mock-функции с настраиваемыми возвращаемыми значениями и отслеживанием вызовов. Для мокирования HTTP-зависимостей в интеграционных тестах Node.js npm-пакет nock перехватывает запросы модулей http и https на сетевом уровне, позволяя тестам имитировать конкретные API-ответы, таймауты и условия ошибок без реального сетевого трафика. Ручные моки, помещённые в директории __mocks__/ рядом с мокируемыми модулями, автоматически используются jest, что удобно для создания согласованных mock-реализаций общих утилит Node.js в рамках всего набора тестов. Эффективная стратегия мокирования в Node.js — использование моков на уровне юнитов, интеграционных тестов с лёгкими in-memory-заглушками и реальных сервисов только в end-to-end-тестах — необходима для поддержания быстрого и надёжного CI-конвейера.
Как это работает
Mocking имеет несколько test-runner: встроенный node:test (Node 20+, без установки), Vitest (быстрый, Vite-native, Jest-совместимый), Jest (зрелый, большая экосистема), Mocha (классический, гибкий). Ассерты: node:assert, chai, expect. Моки: встроенный mock в node:test, sinon, vitest mock. Integration-тесты обычно поднимают приложение + test DB; HTTP-ассерты через supertest. Coverage — через c8 или nyc.
Когда применять
Vitest — для новых проектов: быстрый, ESM-native, watch-mode перезагружает только изменившееся. node:test — для zero-dependency ситуаций (CI-раннеры, внутренности npm-пакетов). Jest — только в legacy. Тесты в CI на каждый PR. Реальная test DB для integration-тестов (testcontainers поднимает на запуск); мокайте только реально внешнее (third-party API, payment-шлюзы).
Типичные ошибки
Ловушки Mocking: тесты, делящие state (строка БД из теста A роняет тест B); over-mocking (тестируете моки, не код); process.exit() в тестах (убивает runner); нет timeout (висящий promise вешает suite); snapshot-тесты на нестабильном выводе (каждое изменение — diff). Тестовый suite — это production-код; рефакторьте его, именуйте хорошо.