React + Enzyme error: Invariant Violation: dangerouslyRenderMarkup(...): Cannot render markup in a worker thread

React + Enzyme error: Invariant Violation: dangerouslyRenderMarkup(...): Cannot render markup in a worker thread

我正在使用 Enzyme 测试 React 组件,但出现以下错误:

Invariant Violation: dangerouslyRenderMarkup(...): Cannot render markup in a worker thread. Make sure window and document are available globally before requiring React when unit testing or use ReactDOMServer.renderToString for server rendering

我在需要 'enzyme' 之前为 jsdom 添加了以下设置(正如我在 places 中读到的):

const baseMarkup = '<!DOCTYPE html><html><head><title></title></head><body></body></html>';
const window = require('jsdom').jsdom(baseMarkup).defaultView;

global.window = window;
global.document = window.document;
global.navigator = window.navigator;

const React = require('react');
const {mount} = require('enzyme');
const sinon = require('sinon');
const SortableInput = require('../../../src/components/sortableInput/sortableInput').default;

我做错了什么?

编辑

我认为这与服务器端渲染无关。该消息是关于单元测试和服务器端呈现的一般信息。

在我的一个项目中,这是初始化 JSDOM 的代码,它工作正常。

import { jsdom } from 'jsdom';

before(() => {
  global.document = jsdom('');
  global.window = document.defaultView;
});

before() 是 Mocha 的根钩子。它在所有测试开始之前运行。

回答我自己的问题,以防有人遇到同样的问题。这最终对我有用:

import 'jsdom-global/register';

describe('My awesome component test', () => {
  let cleanup;

  beforeEach(() => cleanup = require('jsdom-global')());

  afterEach(() => cleanup());

  ....
})

造成相同错误的另一个不太明显的原因是来自 Enzyme 的 describeWithDOM 方法:

describeWithDOM('<Slider />', () => {
   describe('render', () => {
     it('should render the slider with one handle by default', () => {
     // and so on

根据enzyme guide,现在最好避免这种方法:

In previous versions of enzyme, there was a public describeWithDOM API which loaded in a new JSDOM document into the global namespace before every test, ensuring that tests were deterministic and did not have side-effects.

This approach is no longer recommended. React's source code makes several assumptions about the environment it is running in, and one of them is that the global.document that is found at "require time" is going to be the one and only document it ever needs to worry about. As a result, this type of "reloading" ends up causing more pain than it prevents.

It is important, however, to make sure that your tests using the global DOM APIs do not have leaky side-effects which could change the results of other tests. Until there is a better option, this is left to you to ensure.