我有一个导入组件的测试,该组件又导入一个帮助程序文件,该文件使用 window
对象提取查询字符串参数。我收到有关 window
的以下错误:
FAIL src/js/components/__tests__/Controls.test.jsx
● Test suite failed to run
ReferenceError: window is not defined
Controls.jsx:
import { Unwrapped as Controls } from '../Controls'
describe('<MyInterestsControls />', () => {
it('should render the component with the fixture data', () => {
const component = shallow(
<UnwrappedMyInterestControls
dashboardData={dashboardData}
loadingFlags={{ controls: false }}
/>
)
expect(component).toMatchSnapshot()
})
})
Controls.jsx 导入 ./helpers/services.js 其中包含以下内容:
import * as queryString from 'query-string'
const flag = queryString.parse(window.location.search).flag || 'off'
^^^^^^ this seems to be the problem
我试图导入 jsdom:
import { JSDOM } from 'jsdom'
并实现提出的解决方案 here在我的测试文件的顶部:
const { JSDOM } = require('jsdom');
const jsdom = new JSDOM('<!doctype html><html><body></body></html>');
const { window } = jsdom;
function copyProps(src, target) {
const props = Object.getOwnPropertyNames(src)
.filter(prop => typeof target[prop] === 'undefined')
.map(prop => Object.getOwnPropertyDescriptor(src, prop));
Object.defineProperties(target, props);
}
global.window = window;
global.document = window.document;
global.navigator = {
userAgent: 'node.js',
};
copyProps(window, global);
但是,我仍然收到错误消息,似乎 JSDOM 的 window 对象未暴露给测试。
如何正确地将全局对象(如 window
或 document
)暴露给 Jest 测试?
相关package.json
"scripts": {
"test:watch": "NODE_ENV=test jest --watch"
},
...
"devDependencies": {
...
"jest": "^20.0.4",
"jest-mock": "^21.2.0",
"jsdom": "^11.0.0",
...
},
...
"jest": {
"verbose": true,
"collectCoverageFrom": [
"src/js/helpers/preparePayload.js",
"src/js/components-ni",
"!**/node_modules/**",
"!**/dist/**"
],
"coverageThreshold": {
"global": {
"statements": 50,
"branches": 50,
"functions": 50,
"lines": 75
}
},
"testEnvironment": "jest-environment-node"
}
最佳答案
正如@RiZKiT 在下面的评论中提到的,自 Jest v27.0 the default test environment has changed 以来从 "jsdom"
到 "node"
。
您的问题取决于配置。
在你设置的那一刻:
"testEnvironment": "jest-environment-node"
您正在将默认配置从类似于浏览器的 Jest 更改为 jest-environment-node
(Node.js-like) 这意味着您的测试将运行在Node.js下环境
要解决这个问题,您可以将 testEnvironment
设置为 jsdom
或者您从配置中删除 testEnvironment
,因此它将采用您的 package.json
中的默认值:
...
"jest": {
"verbose": true,
"collectCoverageFrom": [
"src/js/helpers/preparePayload.js",
"src/js/components-ni",
"!**/node_modules/**",
"!**/dist/**"
],
"coverageThreshold": {
"global": {
"statements": 50,
"branches": 50,
"functions": 50,
"lines": 75
}
}
}
这是他们在文档中所说的
testEnvironment
[string] # Default: "jsdom"The test environment that will be used for testing. The default environment in Jest is a browser-like environment through jsdom. If you are building a node service, you can use the node option to use a node-like environment instead.
## 你需要 `node` 环境吗?
如我所见,您的测试应该在类似浏览器的环境下运行。
如果您需要一个显式的 Node.js 环境,最好使用 @jest-environment
隔离该情况:
/**
* @jest-environment node
*/
test('use node in this test file', () => {
expect(true).not.toBeNull();
});
或者反过来,如果您打算在 Node.js 环境下运行测试:
/**
* @jest-environment jsdom
*/
test('use jsdom in this test file', () => {
const element = document.createElement('div');
expect(element).not.toBeNull();
});
## 结论
这样你就可以避免手动导入 jsdom
和设置全局变量。 jsdom
将模拟 DOM自动执行。
如果您需要更改测试环境,请使用符号 @jest-environment
。
关于javascript - `window` 没有暴露给 Jest,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46105596/