Имитация динамического требования в Node with Jest

Учитывая пакет npm, который должен динамически загружать зависимость из корня родительского / ссылочного пакета, и это местоположение неизвестно до времени выполнения, он должен выполнить динамическое требование:

// config-fetcher.js
const path = require('path');
const getRunningProjectRoot = require('./get-running-project-root');'
module.exports = filename =>
   require(path.resolve(getRunningProjectRoot(), filename));

(Там нет гарантии, что модуль будет в node_modules, Это может быть символическая ссылка или загружена глобально. Так что он не может использовать статическое требование.)

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

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

const mockFileContents = {};
jest.mock('/absolute/filename.blah', () => mockFileContents);
// in preparation for wanting to do this:
const result = require('./config-fetcher')('/absolute/filename.blah');
expect(result).toBe(mockFileContents);

тогда я получаю ошибку от jest-resolve, с файлом Resolver.resolveModule бросание Error: Cannot find module '/absolute/filename.blah'.

Мне нужно протестировать некоторые функциональные возможности этого динамического модуля, требующего изменения, поскольку он обрабатывает некоторые случаи относительных и абсолютных путей и позволяет вам указать специальный путь через символ, например, один из них applicationRootпоэтому модуль config-fetcher делает тяжелую работу вместо звонящего.

Может ли кто-нибудь предложить руководство о том, как протестировать этот модуль, или как реструктурировать такие динамические требования, которые не нужны, или их проще тестировать?

2 ответа

Решение

Вы можете пройти { virtual: true } как options в jest.mock смоделировать модуль, который не существует:

const { myFunc } = require('does not exist');

jest.mock('does not exist',
  () => ({
    myFunc: () => 'hello'
  }),
  { virtual: true }
);

test('mock file that does not exist', () => {
  expect(myFunc()).toBe('hello');  // Success!
});

подробности

Jest полностью берет на себя require система для тестируемого кода.

Он имеет свой собственный кеш модуля и отслеживает макеты модулей.

Как часть этой системы, Jest позволяет создавать макеты для модулей, которые на самом деле не существуют.

Вы можете пройти options в качестве третьего параметра jest.mock, В настоящее время единственный вариант virtual и если это true затем Jest просто добавит результат вызова функции фабрики модулей в кэш модуля и вернет ее всякий раз, когда это требуется в тестируемом коде.

Кто-нибудь пробовал тестировать динамический импорт? Ниже приведены примеры кодов для тестирования. Если я не использую динамический импорт, jest.mock + virtual: true работает.

      const Routes =  React.lazy(() => import('app2/routes'));

jest.mock('does not exist',
  () => ({
    myFunc: () => 'hello'
  }),
  { virtual: true }
);

test('mock file that does not exist', () => {
  expect(myFunc()).toBe('hello');  // Failed!
});
Другие вопросы по тегам