Имитировать динамические требования в Node with Jest - PullRequest
1 голос
/ 09 мая 2019

Учитывая пакет 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 throwing Error: Cannot find module '/absolute/filename.blah'.

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

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

1 Ответ

1 голос
/ 09 мая 2019

Вы можете передать { 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 просто добавит результат вызова функции фабрики модулей в кэш модуля и вернет ее всякий раз, когда это требуется в тестируемом коде.

...