我想在jest测试套件中模拟节点的内置函数require.resolve
。这是一个问题on repl.it和代码本身的工作示例:
测试对象(作为示例):
const requirer = () => {
try {
return require.resolve('./add')
} catch (error) {
console.error('failed to find a module')
}
}
module.exports = requirer
测试套件:
const requirer = require('./requirer')
describe('attempt to mock require.resolve', () => {
it('does not work', () => {
require.resolve = jest.fn(arg => `./${arg}`)
console.log(
'is require.resolve mocked',
jest.isMockFunction(require.resolve)) // will say true
requirer()
expect(require.resolve).toHaveBeenCalledTimes(1)
expect(require.resolve).toBeCalledWith('')
})
})
在测试套件声明中,一切正常(参见jest.isMockFunction(require.resolve)
的输出)并且模拟工作。但是对于测试主题require.resolve
仍然具有原始功能。
由于这个问题,这不是纯粹的单元测试。
例如,如果我,模拟process.exit
一切都按预期工作。
答案 0 :(得分:0)
所以,不是一个完美的解决方案,但注入(DI)require.resolve到
更简单const requirer = (resolver) => {
try {
return resolver('./add')
} catch (error) {
console.error('failed to find a module')
}
}
module.exports = requirer
现在在测试套件中传递模拟版本的require.resolve
按预期工作
const requirer = require('./ requirer')
describe('attempt to mock require.resolve', () => {
it('works', () => {
require.resolve = jest.fn(arg => `./${arg}`)
console.log(
'is require.resolve mocked',
jest.isMockFunction(require.resolve)) // will say true
requirer(require.resolve)
expect(require.resolve).toHaveBeenCalledTimes(1)
// expect(require.resolve).toBeCalledWith('')
})
})
答案 1 :(得分:0)
我知道这并不是您真正要的东西,但这是我的解决方法,可以“模拟” require.resolve
。
jest中有一个有趣的功能,可让您定义自己的模块解析器:
https://jestjs.io/docs/en/configuration#resolver-string
记住这一点,基本上就是我所做的:
const glob = require('glob');
let mapping = {};
// Looks for "module-resolution.json" files in all the `__tests__` directories
glob
.sync(`${__dirname}/../../packages/**/src/**/__tests__/modules-resolution.json`)
.forEach((file) => {
// For each of them, merges them in the "mapping" object
mapping = { ...mapping, ...require(file) };
});
function resolver(path, options) {
// If the path corresponds to a key in the mapping object, returns the fakely resolved path
// otherwise it calls the Jest's default resolver
return mapping[path] || options.defaultResolver(path, options);
}
module.exports = resolver;
module.exports = {
roots: ['<rootDir>'],
testMatch: ['<rootDir>/packages/**/__tests__/**/*.test.js'],
collectCoverageFrom: ['packages/**/src/**/*.js', '!packages/**/src/__tests__/**'],
resolver: '<rootDir>/test-utils/resolver',
};
modules-resolution.json
文件,如下所示:{
"fake-module": "/path/to/fake-module"
}
到目前为止,这已经为我完成了工作,我认为,从本示例开始,我们可以做一些更复杂但对开发人员更友好的事情! 当然,如果此功能可以直接包含在jest中,那就更好了! 无论如何,我希望这对你们中的某些人有帮助?