Ada*_*kis 26 javascript jestjs
tl;博士是:
1)我怎样才能让Jest使用本机require
函数在我的测试中加载所有模块.
2)在任何测试运行之前,我在哪里/如何修改(即用esm加载器替换)https://github.com/standard-things/esm在一个地方使用require函数,所以所有测试都将使用修改过的要求.
我想将esm-loader与我的Jest测试文件一起使用.为了做到这一点,我需要在任何测试代码运行之前全局修补require函数,例如
require = require("@std/esm")(module, { esm: "js", cjs: true });
在触摸或请求任何其他内容之前,如何告诉Jest执行该代码?
我尝试将两者setupTestFrameworkScriptFile
和一个setupFiles
数组条目指向一个包含它的文件,但都没有工作(尽管我确认两者都运行了).
或者,我用npm脚本启动这些测试
"scripts": {
"test": "jest"
}
Run Code Online (Sandbox Code Playgroud)
是否有一些CLI魔术,我可以加载模块然后运行jest
?
编辑 - testEnvironment
和resolver
选项让我想知道是否甚至使用实际的Node require
函数来加载模块,或者使用自己的模块加载器.如果是这样,我想知道这是否可行.
Tar*_*ani 17
所以这个有点难以开始工作.解决方案非常简单,但我需要一段时间才能使其正常运行.问题是每当你在开玩笑中使用任何模块时
它们都是以下方式加载的
({"Object.":function(module,exports,require,__ dirname,__ filename,global,jest){ /**/*内的模块代码 });
如果你看看 node_modules/jest-runtime/build/index.js:495:510
const dirname = (_path || _load_path()).default.dirname(filename);
localModule.children = [];
localModule.parent = mockParentModule;
localModule.paths = this._resolver.getModulePaths(dirname);
localModule.require = this._createRequireImplementation(filename, options);
const transformedFile = this._scriptTransformer.transform(
filename,
{
collectCoverage: this._coverageOptions.collectCoverage,
collectCoverageFrom: this._coverageOptions.collectCoverageFrom,
collectCoverageOnlyFrom: this._coverageOptions.collectCoverageOnlyFrom,
isInternalModule,
mapCoverage: this._coverageOptions.mapCoverage },
this._cacheFS[filename]);
Run Code Online (Sandbox Code Playgroud)
this._createRequireImplementation(filename, options);
为每个模块提供自定义需求对象.因此,您根本无法在任何地方获得本机需求功能.一旦启动了jest,从那时起加载的每个模块都将具有jest的自定义require
功能.
当我们加载一个模块时,调用的requireModule
方法就jest-runtime
被调用了.以下是相同的摘录
moduleRegistry[modulePath] = localModule;
if ((_path || _load_path()).default.extname(modulePath) === '.json') {
localModule.exports = this._environment.global.JSON.parse(
(0, (_stripBom || _load_stripBom()).default)((_gracefulFs || _load_gracefulFs()).default.readFileSync(modulePath, 'utf8')));
} else if ((_path || _load_path()).default.extname(modulePath) === '.node') {
// $FlowFixMe
localModule.exports = require(modulePath);
} else {
this._execModule(localModule, options);
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,文件的扩展名是否.node
直接加载模块,否则它会调用_execModule
.这个函数和我之前发布的代码转换代码相同
const isInternalModule = !!(options && options.isInternalModule);
const filename = localModule.filename;
const lastExecutingModulePath = this._currentlyExecutingModulePath;
this._currentlyExecutingModulePath = filename;
const origCurrExecutingManualMock = this._isCurrentlyExecutingManualMock;
this._isCurrentlyExecutingManualMock = filename;
const dirname = (_path || _load_path()).default.dirname(filename);
localModule.children = [];
localModule.parent = mockParentModule;
localModule.paths = this._resolver.getModulePaths(dirname);
localModule.require = this._createRequireImplementation(filename, options);
Run Code Online (Sandbox Code Playgroud)
现在,当我们想要修改require
测试函数时,我们需要_execModule
直接导出代码.所以代码应该类似于加载.node
模块
} else if ((_path || _load_path()).default.extname(modulePath) === '.mjs') {
// $FlowFixMe
require = require("@std/esm")(localModule);
localModule.exports = require(modulePath);
} else {
Run Code Online (Sandbox Code Playgroud)
但这样做意味着修补我们想要避免的代码.所以我们做的是避免直接使用jest命令,并创建我们自己的jestload.js
并运行它.加载jest的代码很简单
#!/usr/bin/env node
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
cli = require('jest/bin/jest');
Run Code Online (Sandbox Code Playgroud)
现在我们要_execModule
在cli加载之前修改它.所以我们添加下面的代码
const jestRuntime = require("jest-runtime");
oldexecModule = jestRuntime.prototype._execModule;
jestRuntime.prototype._execModule = function (localModule, options) {
if (localModule.id.indexOf(".mjs") > 0) {
localModule.exports = require("@std/esm")(localModule)(localModule.id);
return localModule;
}
return oldexecModule.apply(this, [localModule, options]);
};
cli = require('jest/bin/jest');
Run Code Online (Sandbox Code Playgroud)
现在是时候进行测试了
//__test__/sum.test.js
sum = require('../sum.mjs').sum;
test('adds 1 + 2 to equal 3', () => {
expect(sum(1, 2)).toBe(3);
});
test('adds 2 + 3 to equal 5', () => {
expect(sum(3, 2)).toBe(5);
});
Run Code Online (Sandbox Code Playgroud)
还有一个sum.mjs
档案
export function sum (x, y) { return x + y }
Run Code Online (Sandbox Code Playgroud)
现在我们进行测试
该解决方案可在以下回购中找到
https://github.com/tarunlalwani/jest-overriding-require-function-stackoverflow
您可以通过运行来克隆和测试解决方案npm test
.