`window`没有暴露给Jest [英] `window` is not being exposed to Jest

查看:216
本文介绍了`window`没有暴露给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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆