node.js - shallow - Llamar a setState en pruebas basadas en jsdom que causan el error "No se puede representar el marcado en un subproceso de trabajo"
react-test-renderer (4)
En el momento de la carga, React determina si puede usar DOM y lo almacena como un valor booleano.
var canUseDOM = !!(
typeof window !== ''undefined'' &&
window.document &&
window.document.createElement
);
ExecutionEnvironment.canUseDOM = canUseDOM;
Esto significa que si se carga antes de que se cumplan esas condiciones, se supone que no puede usar DOM.
Podrías parchearlo en tu antes de cada uno.
require(''fbjs/lib/ExecutionEnvironment'').canUseDOM = true
O podrías fingirlo al principio:
global.window = {}; global.window.document = {createElement: function(){}};
O asegúrese de no cargar React antes de configurar JSDOM, que es la única manera en que estoy seguro, pero también es la más difícil y propensa a errores.
O puede informar de esto como un problema, o inspeccionar la fuente de jest y ver cómo se resuelve.
Estoy probando mis componentes React bajo jsdom usando mi propia pequeña utilidad de "navegador virtual". Funciona bien, hasta que estoy tratando de establecer setState
. Por ejemplo, al probar un control de entrada de edades de niños:
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);
});
});
... en la línea setState
estoy recibiendo:
Error no detectado: Infracción invariante: dangerouslyRenderMarkup (...): no se puede representar el marcado en un subproceso de trabajo. Asegúrese de que la window
y el document
estén disponibles en todo el mundo antes de solicitar React al realizar la prueba de unidad o use React.renderToString para la representación del servidor.
Sé que las window
y document
globales están de hecho establecidos por el TestBrowser basado en TestBrowser
, así:
global.document = jsdom.jsdom(''<html><body></body></html>'', jsdom.level(1, ''core''));
global.window = global.document.parentWindow;
Incluso intenté envolver setState
en un setTimeout(..., 0)
. No ayuda ¿Cómo puedo hacer que los cambios de estado de prueba funcionen?
Nada me funcionó hasta que intenté exigir jsdom-global en el comando mocha:
--require jsdom-global/register
Fuente: https://github.com/rstacruz/jsdom-global/blob/master/README.md#mocha
Si usa Mocha y Babel, necesitará configurar jsdom antes de que los compiladores evalúen el código React.
// setup-jsdom.js
var jsdom = require("jsdom");
// Setup the jsdom environment
// @see https://github.com/facebook/react/issues/5046
global.document = jsdom.jsdom(''<!doctype html><html><body></body></html>'');
global.window = document.defaultView;
global.navigator = global.window.navigator;
Con el --require
arg:
$ mocha --compilers js:babel/register --require ./test/setup-jsdom.js test/*.js
Consulte https://github.com/facebook/react/issues/5046#issuecomment-146222515
También tengo este error usando Babel para probar el código ES6. El punto es que hay una diferencia entre import React from ''react''
y const React = require(''react'')
. Si está usando la sintaxis de import
, entonces todas sus importaciones se harían antes que cualquier otra cosa, por lo que no puede simular una window
o document
antes.
Así que el primer bit es reemplazar la import
por la require
en las pruebas (donde sea importante)
El segundo bit es global.navigator
utilizando global.navigator = global.window.navigator
.
Espero que ayude a alguien.