在导入依赖项之前开玩笑模拟窗口对象

Dan*_*ina 10 javascript unit-testing jestjs

在导入依赖项之前,我需要在窗口对象中设置一个值。假设我有这个代码

\n\n
// foo.test.js\nimport { dependency } from \'./foo\'\n\ndescribe(\'...\', () => {\n  it(\'...\', () => {\n    // use dependency\n  })\n})\n
Run Code Online (Sandbox Code Playgroud)\n\n

但是为了导入依赖项,我需要在中定义一个值window.myValues

\n\n
// foo.js\nexport const dependency = {\n  key: window.myValue.nestedValue\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

该代码在导入文件时会给我一个错误,因为window.myValue.nestedValue试图访问nestedValue未定义的属性。

\n\n

我怎样才能做到这一点?

\n\n

编辑\n按照下面christianeide 的答案,我收到以下错误

\n\n
  \xe2\x97\x8f Test suite failed to run\n\n    TypeError: Cannot convert undefined or null to object\n\n      2 |   delete global.window.myValue\n      3 |   global.window = Object.create(window)\n    > 4 |   global.window.myValue = {\n        |                 ^\n      5 |     nestedValue: \'someValue\'\n      6 |   }\n      7 | }\n\n      at module.exports (jest.setup.js:4:17)\n      at node_modules/@jest/core/build/runGlobalHook.js:82:17\n      at ScriptTransformer.requireAndTranspileModule (node_modules/@jest/transform/build/ScriptTransformer.js:684:24)\n      at node_modules/@jest/core/build/runGlobalHook.js:72:27\n      at pEachSeries (node_modules/p-each-series/index.js:8:9)\n      at async _default (node_modules/@jest/core/build/runGlobalHook.js:58:5)\n      at async runJest (node_modules/@jest/core/build/runJest.js:345:5)\n
Run Code Online (Sandbox Code Playgroud)\n

Mil*_*šić 8

es6 导入是“提升”的,这意味着无论您在代码中的任何位置编写它们,它们都会在执行导入模块之前得到处理,因此导入的模块始终在导入模块之前执行。在您的情况下,这意味着 foo.js 在 foo.test.js 之前执行,因此即使您window在测试中正确模拟了您的属性, foo.js 也不会看到您的模拟。

您可以通过在测试中使用 require 在 的 属性被window模拟后导入 foo.js 来解决这个问题。

// foo.test.js
window.myValue = { nestedValue: MOCK_NESTED_VALUE };

const { dependency } = require('./foo');

describe('...', () => {
  it('...', () => {
    // use dependency
  })
})
Run Code Online (Sandbox Code Playgroud)

正如其他答案所指出的,如果是 的现有“系统”属性myValue之一,您可能必须先将其删除。删除时,不要忘记备份,以便测试后清理时可以恢复。windowwindow.location

  • 惊人的!这正是我一直在寻找的。谢谢! (2认同)