Javascript 在导入依赖项之前Jest模拟窗口对象
在导入依赖项之前,我需要在window对象中设置一个值。假设我有这个密码Javascript 在导入依赖项之前Jest模拟窗口对象,javascript,unit-testing,jestjs,Javascript,Unit Testing,Jestjs,在导入依赖项之前,我需要在window对象中设置一个值。假设我有这个密码 //foo.test.js 从“/foo”导入{dependency} 描述(“…”,()=>{ 它(“…”,()=>{ //使用依赖项 }) }) 但是要导入依赖项,我需要在window.myValues //foo.js 导出常量依赖项={ 关键字:window.myValue.nestedValue } 导入文件时,该代码将给我一个错误,因为window.myValue.nestedValue正在尝试访问未定义的
//foo.test.js
从“/foo”导入{dependency}
描述(“…”,()=>{
它(“…”,()=>{
//使用依赖项
})
})
但是要导入依赖项,我需要在window.myValues
//foo.js
导出常量依赖项={
关键字:window.myValue.nestedValue
}
导入文件时,该代码将给我一个错误,因为window.myValue.nestedValue
正在尝试访问未定义的属性nestedValue
我怎样才能做到
编辑
下面我得到了下面的错误
● Test suite failed to run
TypeError: Cannot convert undefined or null to object
2 | delete global.window.myValue
3 | global.window = Object.create(window)
> 4 | global.window.myValue = {
| ^
5 | nestedValue: 'someValue'
6 | }
7 | }
at module.exports (jest.setup.js:4:17)
at node_modules/@jest/core/build/runGlobalHook.js:82:17
at ScriptTransformer.requireAndTranspileModule (node_modules/@jest/transform/build/ScriptTransformer.js:684:24)
at node_modules/@jest/core/build/runGlobalHook.js:72:27
at pEachSeries (node_modules/p-each-series/index.js:8:9)
at async _default (node_modules/@jest/core/build/runGlobalHook.js:58:5)
at async runJest (node_modules/@jest/core/build/runJest.js:345:5)
尝试将值分配给
global.window
大概是这样的:
delete global.window.myValue;
global.window = Object.create(window);
global.window.myValue = {
nestedValue: 'someValue',
};
这可以在
jest.setup.js
中完成,但您也可以在foo.test.js
中定义值。我可以通过创建setup.js
在窗口对象上附加属性:
global.propertyA = () => {};
global.nestedPropertyB = {
propertyC: () => {}
};
在我的jest.config.js
文件中的setupfileafterenv
中设置文件:
module.exports = {
setupFilesAfterEnv: ['<rootDir>/tests/js/setup.js']
}
module.exports={
setupFilesAfterEnv:['/tests/js/setup.js']
}
es6导入是“提升”的,这意味着无论您在代码中写入它们,它们都会在导入模块执行之前得到处理,因此导入的模块总是在导入模块之前执行。在您的例子中,这意味着foo.js在foo.test.js之前执行,因此即使您在测试中正确地模拟了window
的属性,foo.js也不会看到您的模拟
在模拟window
的属性后,您可以在测试中使用require来导入foo.js,从而绕过此问题
// foo.test.js
window.myValue = { nestedValue: MOCK_NESTED_VALUE };
const { dependency } = require('./foo');
describe('...', () => {
it('...', () => {
// use dependency
})
})
正如其他答案所指出的,如果
myValue
是window
的现有“系统”属性之一,例如window.location
,则可能必须首先删除它。删除时,不要忘记备份它,以便在测试后清理时可以恢复它。这对我不起作用。我用我得到的错误的堆栈跟踪更新了我的问题。我真不敢相信要做我想做的事有那么难。我一定是漏掉了什么你在用什么测试环境?Jsdom/browser或node?我没有明确定义testenvironment,所以我假设我使用的是默认的Jsdom,如果您尝试执行console.log(global.window)代码>,是否注销整个global.window-object?如果id没有,我猜您的jest.config.js已经将testEnvironment
设置为jsdom以外的其他内容。是的,它记录了一个巨大的对象,其中的属性我可以识别为窗口对象的一部分,还有许多我不识别的属性。太棒了!这正是我要找的。谢谢