`window`没有暴露给Jest [英] `window` is not being exposed to Jest
问题描述
我有一个导入组件的测试,该组件又导入一个使用窗口
对象的辅助文件来提取查询字符串参数。我收到以下关于窗口的错误
:
I have a test that imports a component that in turn imports a helper file that uses the window
object to pull out a query string parameter. I get the following error about 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 ,其中包含以下内容:
Controls.jsx imports ./helpers/services.js which contains the following:
import * as queryString from 'query-string'
const flag = queryString.parse(window.location.search).flag || 'off'
^^^^^^ this seems to be the problem
我有试图导入jsdom
I have attempted to import jsdom
import { JSDOM } from 'jsdom'
并实施所提出的解决方案这里在我的测试文件的顶部:
And implement the solution presented here at the top of my test file:
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的窗口对象没有暴露给测试。
however I still get the error and it seems JSDOM's window object isn't exposed to the test.
"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"
}
推荐答案
您的问题取决于配置。
在您设置的那一刻:
"testEnvironment": "jest-environment-node"
您正在将默认配置从类似浏览器的jest更改为 jest-environment-node
(类似节点)意味着您的测试将在 NodeJs
环境下运行
you are changing the default configuration from jest which is browser-like to jest-environment-node
(node-like) meaning that your test will be run under a NodeJs
environment
要解决此问题,请设置 testEnvironment
到 jsdom
或者你删除 testEnvironment
从您的配置中,它将采用 package.json中的默认值
:
To solve it either you set your testEnvironment
to jsdom
Or you remove the testEnvironment
from your config so it will take the default value in yourpackage.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
}
}
}
这就是他们在文档中所说的:
This is what they say in the documentation:
testEnvironment
[string] #Default:jsdom
testEnvironment
[string] # Default: "jsdom"
的测试环境将用于测试。 Jest中的默认环境是通过jsdom的
类浏览器环境。如果要构建节点
服务,则可以使用node选项来使用类似节点的环境
。
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`环境?
正如我所看到的,您的测试应该是在类似浏览器的环境下运行。
Do you need the `node` environment?
As I could see, your tests are meant to be run under a browser-like environment.
如果您需要显式节点环境,最好使用 @jest-environment
隔离该情况:
If you ever need an explicit node environment, better you isolate that case using @jest-environment
:
/**
* @jest-environment node
*/
test('use node in this test file', () => {
expect(true).not.toBeNull();
});
或者如果您打算在节点下运行测试,则相反
环境
/**
* @jest-environment jsdom
*/
test('use jsdom in this test file', () => {
const element = document.createElement('div');
expect(element).not.toBeNull();
});
结论
有了这个,你可以避免手动导入 jsdom
并设置全局变量, jsdom
将模拟 DOM
自动执行。
Conclusion
With this you can avoid importing jsdom
manually and setting global variables, jsdom
will mock the DOM
implementation automatically.
如果您需要更改测试环境,请使用符号 @jest-environment
If you need to change the environment for your tests use the notation @jest-environment
这篇关于`window`没有暴露给Jest的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!