我正在 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 进行服务器渲染之前,请确保 window
和 document
全局可用。
我知道 window
和 document
全局变量确实是由基于 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/