Имитация динамического требования в 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!
});