jsdom ベースのテストで setState を呼び出すと、「ワーカー スレッドでマークアップをレンダリングできません」というエラーが発生する 質問する

jsdom ベースのテストで setState を呼び出すと、「ワーカー スレッドでマークアップをレンダリングできません」というエラーが発生する 質問する

私はReactコンポーネントをテストしていますjsdom使用して私自身の小さな「仮想ブラウザ」ユーティリティ。試してみるまでは問題なく動作しますsetState。たとえば、子供の年齢の入力コントロールをテストする場合:

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私が受け取っている電話は次のとおりです:

windowキャッチされないエラー: 不変違反: dangerouslyRenderMarkup(...): ワーカー スレッドでマークアップをレンダリングできません。ユニット テスト時に React を要求する前に、およびがグローバルに使用可能であることを確認するか、documentサーバー レンダリングに React.renderToString を使用してください。

windowおよびdocumentグローバルは、次のように jsdom ベースによって実際に設定されていることがわかっていますTestBrowser

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

setStateにラップしてみましたがsetTimeout(..., 0)、効果がありません。状態の変化をテストするにはどうすればいいでしょうか?

ベストアンサー1

ロード時に、React は DOM を使用できるかどうかを判断し、それをブール値として保存します。

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 のソースを調べて、どのように解決されるかを確認することもできます。

おすすめ記事