react + 酶错误:不变违规:危险地渲染标记(...):无法在工作线程中呈现标记

IT技术 reactjs jsdom enzyme server-side-rendering
2021-04-30 05:03:53

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

不变违规:危险地渲染标记(...):无法在工作线程中呈现标记。在单元测试或使用 ReactDOMServer.renderToString 进行服务器渲染时需要 React 之前,确保windowdocument全局可用

在需要“酶”之前,我为 jsdom 添加了以下设置(正如我在几个地方读到的):

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;

我在这里做错了什么?

编辑

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

3个回答

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

import 'jsdom-global/register';

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

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

  afterEach(() => cleanup());

  ....
})

在我的一个项目中,这是初始化 JSDOM 的代码,它运行良好。

import { jsdom } from 'jsdom';

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

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

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

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

根据酶指南现在最好避免这种方法:

在之前的酶版本中,有一个公共的 describeWithDOM API,它在每次测试之前将一个新的 JSDOM 文档加载到全局命名空间中,以确保测试是确定性的并且没有副作用。

不再推荐这种方法。React 的源代码对其运行的环境做了几个假设,其中之一是在“需要时间”找到的 global.document 将是它需要担心的唯一一个文档。结果,这种类型的“重新加载”最终会导致比它阻止的更多的痛苦。

然而,重要的是要确保使用全局 DOM API 的测试没有可能改变其他测试结果的泄漏副作用。在有更好的选择之前,这由您来确保。