node.js - 在基于 jsdom 的测试中调用 setState 导致 "Cannot render markup in a worker thread"错误

标签 node.js testing reactjs jsdom reactjs-testutils

我正在 jsdom 下测试我的 React 组件使用 my own tiny "virtual browser" utility.工作得很好,直到我尝试 setState。例如,在测试 child 年龄输入控件时:

describe('rendering according to the draft value', function () {
    var component;

    beforeEach(function () {
        component = TestUtils.renderIntoDocument(
            React.createElement(ChildrenInput, {value: []})
        );

        component.setState({draft: [{age: null}, {age: null}]}, done);
    });

    it('overrides the value property for the count', function () {
        assert.strictEqual(component.refs.count.props.value, 2);
    });

    it('overrides the value property for the ages', function () {
        assert.strictEqual(component.refs.age1.props.value, null);
    });
});

…在我得到的 setState 行:

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

我知道 windowdocument 全局变量确实是由基于 jsdom 的 TestBrowser 设置的,如下所示:

global.document = jsdom.jsdom('<html><body></body></html>', jsdom.level(1, 'core'));
global.window = global.document.parentWindow;

我什至尝试将 setState 包装到 setTimeout(..., 0) 中。它没有帮助。如何使测试状态更改起作用?

最佳答案

在加载时,React 确定它是否可以使用 DOM,并将其存储为 bool 值。

var canUseDOM = !!(
  typeof window !== 'undefined' &&
  window.document &&
  window.document.createElement
);
ExecutionEnvironment.canUseDOM = canUseDOM;

这意味着如果它在这些条件成立之前被加载,它假定它不能使用 DOM。

你可以在你的 beforeEach 中修改它。

require('fbjs/lib/ExecutionEnvironment').canUseDOM = true

或者你可以先假装它:

global.window = {}; global.window.document = {createElement: function(){}};

或者确保在设置 JSDOM 之前不加载 React,这是我比较肯定的唯一方法,但它也是最困难且最容易出错的方法。

或者您可以将此作为问题报告,或检查 jest 的来源,看看它是如何解决的。

关于node.js - 在基于 jsdom 的测试中调用 setState 导致 "Cannot render markup in a worker thread"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26867535/

相关文章:

javascript - 在 React 中将一个数组中的值分配给另一个数组

javascript - array.fill.call() 在 js 中如何工作?

node.js - 停止回调链并在 Save 方法 ApostropeCMS 之前发送通知

node.js - 如何通过 MongoDB 中的键查询子文档的映射?

php - 如果事件已被分派(dispatch),如何在功能测试中进行测试

Swift 测试给出错误 "Undefined symbols for architecture x86_64"

javascript - 在 ReactJS 前端中使用 Meteor react 变量

javascript - 无法使用 Node 下载 S3 对象

javascript - 解析组合表情符号

javascript - 当我通过 document.getElementById 更新值时,React 不会触发 onChange 事件