Mocking node-fetch с помощью jest, создающего объект ответа для имитации

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

Инициализация,

jest.mock('node-fetch')
const fetch = require('node-fetch')
const { Response, Headers } = jest.requireActual('node-fetch')

// Example adapted from https://fetch.spec.whatwg.org/#example-headers-class
const meta = {
  'Content-Type': 'application/json',
  'Accept': '*/*',
  'Breaking-Bad': '<3'
}
// You can in fact use any iterable objects, like a Map or even another Headers
const headers = new Headers(meta)
const copyOfHeaders = new Headers(headers)

const ResponseInit = {
  status: 200,
  statusText: 'fail',
  headers: headers
}

С базовым тестом

  test('Basic Test', async () => {
    const token = ''
    const getDocList = new Response(JSON.stringify(downloadDocumentData), ResponseInit)
    fetch.mockResolvedValueOnce(Promise.resolve(getDocList))
    await module.doSomething('mock', token)
      .then( async(res) => {
        await expect(res.data).toEqual(Object)
      })
  }, 5000)

Я получаю сообщение об ошибке

     FetchError {
        message:
         'invalid json response body at  reason: Unexpected token H in JSON at position 2',
        type: 'invalid-json' }

Как я могу инициализировать ответ для действительного json, я пробовал много разных вещей.

После статьи на https://jestjs.io/docs/en/bypassing-module-mocks, но вместо этого я хочу вернуться и протестировать json.


person GrandFleet    schedule 31.10.2019    source источник


Ответы (1)


Мы должны использовать jest.mock (имя модуля, фабрика, параметры) имитировать node-fetch модуль и fetch функцию.

Чтобы создать объект ответа функции fetch, вам необходимо использовать класс Response, предоставляемый модулем node-fetch, поэтому используйте jest.requireActual (moduleName), чтобы получить исходный, разблокированный node-fetch модуль и Response класс.

Конечно, мы можем построить объект ответа произвольно, но экземпляр класса Response действительно близок к реальному ответу.

То же самое и с объектом headers.

Вот рабочая демонстрация:

index.js:

const fetch = require('node-fetch');

module.exports = {
  async doSomething(url, token) {
    return fetch(url).then(res => res.json());
  }
};

index.spec.js:

jest.mock('node-fetch');

const fetch = require('node-fetch');
const { Response, Headers } = jest.requireActual('node-fetch');
const mod = require('./');

const meta = {
  'Content-Type': 'application/json',
  Accept: '*/*',
  'Breaking-Bad': '<3'
};
const headers = new Headers(meta);
const copyOfHeaders = new Headers(headers);

const ResponseInit = {
  status: 200,
  statusText: 'fail',
  headers: headers
};

test('Basic Test', async () => {
  const token = '';
  const downloadDocumentData = { data: {} };
  const getDocList = new Response(JSON.stringify(downloadDocumentData), ResponseInit);
  fetch.mockResolvedValueOnce(Promise.resolve(getDocList));
  const res = await mod.doSomething('mock', token);
  expect(res).toEqual({ data: {} });
  expect(fetch).toBeCalledWith('mock');
});

Результат модульного теста:

 PASS  src/stackoverflow/58648691/index.spec.js
  ✓ Basic Test (5ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        2.557s

Исходный код: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/58648691

person slideshowp2    schedule 01.11.2019