我试图测试呈现iframe并将标记直接注入该iframe的React组件。 (我没有尝试在iframe中加载网址。)
该组件在浏览器中实际上运行良好,但到目前为止编写测试似乎是不可能的。我不确定为什么。
这是一个缩短的测试案例,证明了失败。
// Set up DOM
var jsdom = require( 'jsdom' ).jsdom;
global.document = jsdom( '' );
global.window = document.defaultView;
global.navigator = document.defaultView.navigator;
// Prepare React
var ReactTestUtils = require( 'react-addons-test-utils' );
var React = require( 'react' );
var Frame = React.createClass( {
componentDidMount() {
console.log( 'iframe loaded. adding content' );
const iframe = this.refs.iframe;
console.log( 'adding content to', iframe.contentWindow ); // Should not be null
iframe.contentWindow.document.open();
iframe.contentWindow.document.write( 'Hello World!' );
iframe.contentWindow.document.close();
},
render() {
console.log( 'rendering iframe' );
return React.createElement( 'iframe', { ref: 'iframe' } );
}
} );
// Render the component
ReactTestUtils.renderIntoDocument( React.createElement( Frame ) );
要运行此功能,您需要安装以下npm软件包:jsdom,react,react-addons-test-utils。您应该能够使用node运行上面的代码。
答案 0 :(得分:4)
我对您的代码进行了彻底的测试,结果发现问题是ReactTestUtils.renderIntoDocument
。
ReactTestUtils.renderIntoDocument
为Component创建一个容器,但不再附加到DOM,因此contentWindow
为iframe
元素的原因为ReactTestUtils
。如果您阅读了renderIntoDocument
来源中的评论,您会发现他们正在考虑重命名ReactDOM
,因为从技术上讲,它不会!
似乎解决方案是直接使用ReactTestUtils
。
以下是var ReactTestUtils = {
renderIntoDocument: function (instance) {
var div = document.createElement('div');
// None of our tests actually require attaching the container to the
// DOM, and doing so creates a mess that we rely on test isolation to
// clean up, so we're going to stop honoring the name of this method
// (and probably rename it eventually) if no problems arise.
// document.documentElement.appendChild(div);
return ReactDOM.render(instance, div);
},
}
来源的一些代码:
ReactDOM
在您的测试用例中使用// Set up DOM
var jsdom = require( 'jsdom' ).jsdom;
global.document = jsdom( '' );
global.window = document.defaultView;
global.navigator = document.defaultView.navigator;
// Prepare React
var ReactTestUtils = require( 'react-addons-test-utils' );
var React = require( 'react' );
var ReactDOM = require('react-dom')
var Frame = React.createClass( {
componentDidMount() {
console.log( 'iframe loaded. adding content' );
const iframe = this.refs.iframe;
console.log( 'adding content to', iframe.contentWindow ); // Should not be null
iframe.contentWindow.document.open();
iframe.contentWindow.document.write( 'Hello World!' );
iframe.contentWindow.document.close();
// Should log "Hello World!"
console.log(iframe.contentWindow.document.body.innerHTML);
},
render() {
console.log( 'rendering iframe' );
return React.createElement( 'iframe', { ref: 'iframe' } );
}
} );
// Render the component
// NOPE
//ReactTestUtils.renderIntoDocument( React.createElement( Frame ) );
// YUP
ReactDOM.render(React.createElement(Frame), document.body)
:
ReactTestUtils
在Test.class
的文档中没有提到这一点太糟糕了。
答案 1 :(得分:1)
在contentWindow可用之前,您需要将iframe附加到文档中。
检查此代码:
var iframe = document.createElement('iframe');
console.log(iframe.contentWindow);
document.body.appendChild(iframe);
console.log(iframe.contentWindow);