# JavaScript-тестирование с Jest: от настройки окружения до сложных асинхронных моков

Источник: https://www.youtube.com/watch?v=IPiUDhwnZxA
Канал: freeCodeCamp.org
Опубликовано: 13.12.2023

---

Эта статья представляет собой подробное руководство по использованию Jest — одного из самых популярных фреймворков для тестирования JavaScript-кода. Ведущий курса Томми (Tommy) от freeCodeCamp разбирает путь от инициализации проекта до продвинутых техник: работы с асинхронным кодом, создания моков и использования «шпионов» (spies) для отслеживания поведения функций.

## 🛠️ Первые шаги: установка и настройка среды
[[JUMP:00:15]]

Процесс работы с Jest начинается с подготовки рабочего пространства. Автор демонстрирует стандартный цикл инициализации Node.js проекта [01:36]:

1.  **Инициализация:** Использование команды `npm init -y` позволяет быстро создать файл `package.json` со стандартными настройками, пропустив все уточняющие вопросы системы [01:50].
2.  **Установка Jest:** Фреймворк устанавливается как зависимость для разработки (`devDependencies`) командой `npm install --save-dev jest` [03:13]. Томми подчеркивает, что Jest выбирается за его простоту и богатый функционал «из коробки» [03:28].
3.  **Конфигурация скриптов:** В файле `package.json` необходимо изменить секцию `scripts`, чтобы команда `npm test` запускала именно `jest` [05:53].

## 🧪 Основы модульного тестирования
[[JUMP:06:45]]

Центральным понятием курса является **юнит-тестирование** (Unit Testing). По определению Томми, это процесс проверки небольших, изолированных фрагментов кода (функций или классов) для раннего обнаружения ошибок [06:57]. Раннее тестирование критично: оно позволяет локализовать проблему в конкретном блоке кода до того, как она превратится в трудноуловимый баг в составе всей системы [07:23].

Пример простейшего теста:

*   Создается файл `sum.js` с функцией сложения двух чисел.
*   Функция экспортируется через `module.exports` [08:57].
*   Создается файл теста `sum.test.js`. Использование слова `.test.` в названии файла — это стандарт, по которому Jest автоматически идентифицирует файлы с тестами [10:00].

Структура любого теста в Jest строится на функции `test(description, callback)`, где внутри колбэка используется связка `expect(...)` и матчер (matcher), например `.toBe(...)` [12:03].

## 🎯 Работа с матчерами: от чисел до ошибок
[[JUMP:15:36]]

Матчеры в Jest — это инструменты, позволяющие проверять значения различными способами. Томми выделяет несколько ключевых типов:

1.  **`.toBe()`**: Используется для сравнения примитивных значений (числа, строки, булевы значения) [16:40].
2.  **`.toEqual()`**: Необходим при тестировании объектов и массивов. Он проверяет не идентичность ссылок в памяти, а рекурсивное равенство всех свойств объекта [19:40].
3.  **`.toBeTruthy()` и `.toBeFalsy()`**: Проверяют значения в логическом контексте (например, является ли значение `null`, `0` или `undefined`) [21:52].
4.  **`.toThrow()`**: Критически важный инструмент для обработки ошибок [25:15]. Тест считается успешным, если функция выбрасывает исключение при передаче некорректных данных (например, строки вместо ожидаемого числа) [26:46].

## ⏳ Тестирование асинхронного кода
[[JUMP:33:26]]

Асинхронность — одна из самых сложных тем в тестировании JavaScript, так как выполнение кода не блокирует основной поток [34:04]. Томми разбирает три подхода к тестированию таких операций:

### Callbacks (Обратные вызовы)
Для корректного тестирования колбэков нужно использовать специальный аргумент `done`. Это сигнал для Jest, что тест не завершен до тех пор, пока эта функция не будет вызвана [37:24]. Если забыть `done`, тест завершится раньше, чем придет ответ от асинхронной функции.

### Promises (Промисы)
При работе с промисами тест должен возвращать промис (использование `return`). Для проверки результата используются специальные методы:

*   `.resolves` — для успешного выполнения [44:14].
*   `.rejects` — для проверки случаев, когда промис должен завершиться ошибкой [45:28].

### Async/Await
Этот синтаксис считается наиболее читаемым и современным [49:28]. Ключевое слово `async` перед тестовой функцией позволяет использовать `await` внутри, приостанавливая выполнение теста до момента разрешения промиса [49:13].

## 🎭 Имитация поведения: Моки и Шпионы
[[JUMP:49:54]]

Моки (Mocks) и шпионы (Spies) — инструменты изоляции кода. Они позволяют заменить медленные или внешние зависимости (базы данных, API) «фейковыми» реализациями [50:35].

*   **Mock-функции (`jest.fn()`):** Позволяют создать функцию-пустышку, которой можно задать возвращаемое значение. Это ускоряет тесты и делает их надежными, так как они перестают зависеть от стабильности внешних сервисов [51:19].
*   **Spies (`jest.spyOn()`):** В отличие от моков, шпионы не всегда заменяют логику функции, но позволяют отслеживать её вызовы: сколько раз вызывалась, с какими аргументами и что вернула [50:08].

Особое внимание Томми уделяет методу `spy.mockRestore()`. Он необходим для того, чтобы вернуть функции её оригинальное поведение после завершения теста, предотвращая влияние тестов друг на друга [59:43].