Calling setState in jsdom-based tests causing "Cannot render markup in a worker thread" error Calling setState in jsdom-based tests causing "Cannot render markup in a worker thread" error reactjs reactjs

Calling setState in jsdom-based tests causing "Cannot render markup in a worker thread" error


At load time React determines if it can use DOM, and stores it as a boolean.

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

This means that if it's loaded before those conditions will be true, it assumes it can't use DOM.

You could monkey patch it in your beforeEach.

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

Or you could fake it at first:

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

Or ensure that you don't load React before you set up JSDOM, which is the only way I'm positive about, but it's also the most difficult and bug prone.

Or you could report this as an issue, or inspect jest's source and see how it resolves it.


If you use Mocha and Babel, you will need to setup jsdom before the compilers evaluate the React code.

// setup-jsdom.jsvar jsdom = require("jsdom");// Setup the jsdom environment// @see https://github.com/facebook/react/issues/5046global.document = jsdom.jsdom('<!doctype html><html><body></body></html>');global.window = document.defaultView;global.navigator = global.window.navigator;

With the --require arg:

$ mocha --compilers js:babel/register --require ./test/setup-jsdom.js test/*.js

See https://github.com/facebook/react/issues/5046#issuecomment-146222515

Source


I've also got this error using Babel for testing ES6 code. The point is that there's a difference between import React from 'react' and const React = require('react'). If you're using import syntax, then all your imports would happend before anything else, so you can't mock window or document before.

So first bit is to replace import by require in the tests(where it matters)

The second bit is to mock global.navigator by using global.navigator = global.window.navigator.

Hope it'll help somebody.