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