Jest: восстановить оригинальную реализацию модуля на ручном макете - PullRequest
0 голосов
/ 11 января 2019

У меня довольно распространенный вариант использования для тестирования, и я не уверен, какой там лучший подход.

Контекст

Я бы хотел протестировать модуль, который зависит от пользовательской зависимости . Зависимость пользовательской области (neat-csv) экспортирует одну функцию, которая возвращает Promise .

Цель

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

AFAIK, я не могу использовать jest.spyOn здесь, поскольку модуль экспортирует одну функцию.

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

Упрощенный пример

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

'use strict';

const neatCsv = require('neat-csv');

async function convertCsvToJson(apiResponse) {
  try {
    const result = await neatCsv(apiResponse.body, {
      separator: ';'
    });
    return result;
  } catch (parseError) {
    throw parseError;
  }
}

module.exports = {
  convertCsvToJson
};

А вот попытка тестирования, которая не проходит во втором тесте (немодальная версия):

'use strict';

let neatCsv = require('neat-csv');
let { convertCsvToJson } = require('./module-under-test.js');

jest.mock('neat-csv', () =>
  jest.fn().mockRejectedValueOnce(new Error('Error while parsing'))
);

const csv = 'type;part\nunicorn;horn\nrainbow;pink';
const apiResponse = {
  body: csv
};

const rejectionOf = (promise) =>
  promise.then(
    (value) => {
      throw value;
    },
    (reason) => reason
  );

test('mocked version', async () => {
  const e = await rejectionOf(convertCsvToJson(apiResponse));
  expect(neatCsv).toHaveBeenCalledTimes(1);
  expect(e.message).toEqual('Error while parsing');
});

test('non mocked version', async () => {
  jest.resetModules();
  neatCsv = require('neat-csv');
  ({ convertCsvToJson } = require('./module-under-test.js'));

  const result = await convertCsvToJson(apiResponse);
  expect(JSON.stringify(result)).toEqual(
    '[{"type":"unicorn","part":"horn"},{"type":"rainbow","part":"pink"}]'
  );
});

Мне интересно, предназначен ли jest для таких вещей или я иду по неправильному пути и должен вместо этого ввести neat-csv?

Каким был бы идиоматический способ справиться с этим?

1 Ответ

0 голосов
/ 11 января 2019

Да, Jest - это , предназначенный для таких вещей.

Метод API, который вы ищете, это jest.doMock . Он предоставляет способ имитации модулей без неявного подъема, который происходит с jest.mock , позволяя вам макетировать в области тестов.

Вот рабочий пример вашего тестового кода, который показывает это:

const csv = 'type;part\nunicorn;horn\nrainbow;pink';
const apiResponse = {
    body: csv
};

const rejectionOf = promise =>
    promise.then(value => {
        throw value;
    }, reason => reason);

test('mocked version', async () => {
    jest.doMock('neat-csv', () => jest.fn().mockRejectedValueOnce(new Error('Error while parsing')));
    const neatCsv = require('neat-csv');
    const { convertCsvToJson } = require('./module-under-test.js');
    const e = await rejectionOf(convertCsvToJson(apiResponse));
    expect(neatCsv).toHaveBeenCalledTimes(1);
    expect(e.message).toEqual('Error while parsing');
    jest.restoreAllMocks();
});

test('non mocked version', async () => {
    const { convertCsvToJson } = require('./module-under-test.js');

    const result = await convertCsvToJson(apiResponse);
    expect(JSON.stringify(result)).toEqual('[{"type":"unicorn","part":"horn"},{"type":"rainbow","part":"pink"}]');
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...