Jest: восстановить оригинальную реализацию модуля на ручном макете

1

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

контекст

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

Цель

Я хочу neat-csv поведение 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?

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

Теги:
unit-testing
jestjs

1 ответ

0
Лучший ответ

Да, 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');
});

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"}]');
});
  • 0
    Я просто имел возможность попробовать, но по некоторым причинам это не работает. Я вообще не использую babel в своем проекте. Метод doMock работает только тогда, когда в проекте используется babel-jest?
  • 0
    Я на самом деле настроил рабочую версию теста на моей локальной машине, так что я уверен, что код из моего ответа работает. Это для меня.
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню