Как unit test API-вызовы с посмеянной выборкой() в реакции-родной с Jest

В React Native я использую fetch для выполнения сетевых запросов, однако fetch не является явно обязательным модулем, поэтому в Jest кажется невозможным насмехаться над ним.

Даже попытка вызвать метод, который использует fetch в тесте, приведет к:

ReferenceError: выборка не определена

Есть ли способ проверить такие запросы API в реагировать нативно с Jest?

Ответы

Ответ 1

Внутри вашего теста вы можете смоделировать любую функцию, которую хотите, используя Jest mocks:

fetch = jest.fn(() => Promise.resolve());

Этот подход работает только для тестовых случаев на основе обещаний (см. pit в документации Jest).

Поскольку fetch является асинхронной функцией, вам необходимо запустить все свои тесты, используя pit (подробнее об асинхронных тестах здесь).

Ответ 2

Другой подход, где вы издеваетесь над глобальным объектом fetch:

const mockSuccesfulResponse = (
  status = 200,
  method = RequestType.GET,
  returnBody?: object
) => {
  global.fetch = jest.fn().mockImplementationOnce(() => {
    return new Promise((resolve, reject) => {
      resolve({
        ok: true,
        status,
        json: () => {
          return returnBody ? returnBody : {};
        },
      });
    });
  });
};

Приведенный выше вспомогательный метод может быть изменен любым способом :-) Надеюсь, он кому-нибудь поможет

Ответ 3

Вместо того, чтобы бросать свой собственный макет, вы можете использовать пакет npm jest-fetch-mock для переопределения глобального объекта выборки. Этот пакет позволяет настроить поддельные ответы и проверить отправленные запросы. Смотрите эту ссылку для подробных примеров использования.

Ответ 4

Я решил это, добавив isomorphic-fetch.

$ npm install --save isomorphic-fetch

и используя его как

import fetch from 'isomorphic-fetch';
...
fetch('http://foo.com');

whatwg-fetch может также работать

Ответ 5

Как рекомендовано @ArthurDenture, вы можете использовать fetch-mock, но вам нужно установить несколько дополнительных пакетов, чтобы он работал с React Native и Jest:

$ npm install --save-dev fetch-mock
$ npm install --save-dev babel-plugin-transform-runtime
$ npm install --save-dev babel-preset-env

Затем вы можете смоделировать выборочные запросы в ваших тестах. Вот пример:

// __tests__/App.test.js
import React from 'react';
import App from '../App';
import fetchMock from 'fetch-mock';
import renderer from 'react-test-renderer';

it('renders without crashing', () => {
  fetchMock.mock('*', 'Hello World!');
  const rendered = renderer.create(<App />).toJSON();
  expect(rendered).toBeTruthy();
});

Ответ 6

Это сработало для меня, добавив эту строку в тестовую функцию:

window.fetch = jest.fn(() => new Promise(resolve => resolve()));

Это очень похоже на ответ @Alexey Kureev, но я добавляю макет функции к объекту window, чтобы сделать его доступным для всех.

Ответ 7

Предположим, что вы хотите проверить разрешение и отклонить случаи, для этого сначала вы смоделируете поведение выборки, а затем используете Jest, отклоняя и разрешая методы с помощью блока утверждений


function fetchTodos() {
  return fetch('${window.location.origin}/todos.json')
    .then(response => response.json())
    .catch(error => console.log(error))
}
describe('fetchTodos', () => {
  it('returns promise resolving to parsed response', () => {
    global.fetch = jest.fn(() => Promise.resolve({ json: () => ''}))
    expect(fetchTodos()).resolves.toBe('');
  })
  it('returns promise handling the error', async () => {
    global.fetch = jest.fn(() => Promise.reject(''))
    expect(fetchTodos()).rejects.toBe('')
  })
})