Мокинг и тестирование выборки с помощью Jest

Вот небольшое примечание о насмешке и тестировании fetch вызовов с помощью Jest.

Возьмем пример компонента React, ExampleComponent:

Напишем для него тест с помощью Jest и Enzyme, ExampleComponent.test.js:

Вот некоторые моменты, на которые следует обратить внимание:

  1. Передавая здесь функцию done, мы говорим Jest дождаться вызова обратного вызова done перед завершением теста. См. Дополнительную информацию в документации Тестирование асинхронного кода.
  2. Поскольку мы await вызов response.json() в ExampleComponent.js, мы Promise.resolve это в тесте mockSuccessResponse объект.
  3. Поскольку мы await ожидаем вызов fetch('https://url-of-your-server.com/example/json') в ExampleComponent.js и ожидаем, что возвращаемый объект будет содержать json функцию, которая возвращает другой Promise, мы Promise.resolve к объекту, содержащему такую ​​json функцию.
  4. Мы шпионим за window.fetch и имитируем его реализацию, чтобы вернуть объект Promise, описанный в 3. См. Раздел ниже, если вы получаете сообщение об ошибке типа Невозможно шпионить за свойством выборки, потому что это не функция; undefined дано вместо .
  5. Мы вызываем Enzyme для поверхностного рендеринга, который также вызывает методы жизненного цикла React *.
  6. Помещение нашего кода утверждения в process.nextTick() гарантирует, что функции, поставленные в очередь в текущем цикле событий, завершены, что также гарантирует, что наши Promise и другой код внутри ExampleComponent будут выполнены.
  7. По желанию мы очищаем макет.
  8. Мы вызываем done, чтобы сообщить Jest, что этот тестовый пример завершен.

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

«Невозможно проследить за свойством выборки, потому что это не функция; undefined дано вместо "

Если вы получите сообщение об ошибке: Невозможно проследить за свойством выборки, потому что это не функция; undefined указано вместо ”, потому что fetch не был полифиллен в среде JSDOM вашего Jest. На момент написания этой статьи существует открытый запрос («jsdom / jsdom # 1724) на добавление fetch заголовков API в JSDOM.

В качестве обходного пути вместо использования jest.spyOn вы можете…

global.fetch = jest.fn().mockImplementation(() => mockFetchPromise);

… И очистить его позже, используя…

global.fetch.mockClear();
delete global.fetch;

* Примечание о методах жизненного цикла React и Enzyme v3:

Начиная с Enzyme v3, shallow API вызывает такие методы жизненного цикла React, как componentDidMount и componentDidUpdate.