给定一个需要从父包/引用包的根目录动态加载依赖项的npm包,并且该位置直到运行时才知道,它必须执行一个动态require:
// config-fetcher.js
const path = require('path');
const getRunningProjectRoot = require('./get-running-project-root');
module.exports = filename =>
require(path.resolve(getRunningProjectRoot(), filename));
(不能保证模块在node_modules
中,它可能是符号链接的,也可能是全局加载的,所以不能使用静态require。)
这是从真实的代码中简化而来的,所以除非您知道一种方法,可以相对于运行的项目根目录非动态地请求文件,否则就必须这样做。
现在,为了测试这一点,我不希望依赖于任何实际存在于磁盘上的文件,但是,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'.
我需要测试这个动态请求模块的一些功能,因为它处理相对路径与绝对路径的一些情况,并允许您通过Symbol指定一个特殊的路径,例如applicationRoot
,因此模块config-fetcher
代替调用者完成了繁重的工作。
有谁能提供一些指导,告诉我们如何测试这个模块,或者如何重新构造,以便不需要动态需求,或者使它们更容易测试吗?
1条答案
按热度按时间pftdvrlh1#
可以在
jest.mock
中将{ virtual: true }
作为options
传递,以模拟不存在的模块:Jest
完全接管了require
系统的测试代码。它有自己的模块缓存并跟踪模块模拟。
作为这个系统的一部分,
Jest
允许您为实际上不存在的模块创建模拟。您可以将
options
作为第三个参数传递给jest.mock
,目前唯一的选项是virtual
,如果是true
,则Jest
会简单地将调用模块工厂函数的结果添加到模块缓存中,并在测试代码需要时将其返回。