使用 renderIntoDocument 测试功能组件
Testing functional components with renderIntoDocument
我正在学习使用 ReactTestUtils 库测试 React 无状态组件。这是我的简单组件:
import React from 'react';
const Greeter = ({name,place}) => (
<h1>Hello,{name}. Welcome to the {place}.</h1>
);
export default Greeter;
这是我的测试规范,为了让 renderIntoDocument
正常工作,我按照建议 here 将 Greeter 组件包装在 div 中:
import {expect} from 'chai';
import React from 'react';
import ReactTestUtils from 'react-addons-test-utils';
import Greeter from '../Greeter';
describe('Greeter Components',() => {
it('renders correctly',() => {
var component = ReactTestUtils.renderIntoDocument(<div>
<Greeter name="Vamsi" place="Hotel California"/>
</div>);
var hasH1 = ReactTestUtils.findRenderedDOMComponentWithTag(component,'h1');
expect(hasH1).to.be.ok;
});
});
我收到错误
findAllInRenderedTree(...): instance must be a composite component.
我将我的代码提供为 jsbin here。
由于函数组件没有与之关联的实例,因此您不能直接将它们与 render 或 renderIntoDocument 一起使用。尝试包装函数组件是个好主意,不幸的是,由于类似的原因,使用 div
不起作用。 DOM 组件也不是 return 组件实例,而是 return 底层 DOM 节点。
这就是说您不能使用测试实用程序函数 或 本机组件作为您正在渲染的 "root" 组件。相反,您将希望将功能组件包装在使用 createClass
或扩展 React.Component
.
的包装器组件中
class Wrapper extends React.Component {
render() {
return this.props.children
}
}
let component = renderIntoDocument(<Wrapper><Greeter /></wrapper>
像这样的陷阱可能是充分利用第三方测试库的理由,比如流行的酶,或者我自己的看法:teaspoon。两者都通过为您无缝包装和展开功能组件来抽象此类问题,因此您无需担心要呈现的组件类型。
在 <div>
中包装功能组件对我有用。您只需要稍微不同地搜索要测试的组件,即
const props = { p1: "1" }
test('Foo renders correctly classed div', () => {
const cpt = TestUtils.renderIntoDocument(<div><Foo {...props} /></div>);
const myNode = ReactDOM.findDOMNode(cpt.childNodes[0]);
expect(myNode.className).toBe('my-class');
});
请注意,您可以使用 cpt.childNodes[0]
定位 myNode
进行测试
为了改进@monastic-panic 的回答,我的两分钱:
您不必为此创建 class。动态执行:
import createReactClass from 'create-react-class';
// need to be a class component
const Clazz = createReactClass({
render: () => {
return <YourFunctionalComponentName {...props} />;
},
});
ReactTestUtils.renderIntoDocument(<Clazz />);
我正在学习使用 ReactTestUtils 库测试 React 无状态组件。这是我的简单组件:
import React from 'react';
const Greeter = ({name,place}) => (
<h1>Hello,{name}. Welcome to the {place}.</h1>
);
export default Greeter;
这是我的测试规范,为了让 renderIntoDocument
正常工作,我按照建议 here 将 Greeter 组件包装在 div 中:
import {expect} from 'chai';
import React from 'react';
import ReactTestUtils from 'react-addons-test-utils';
import Greeter from '../Greeter';
describe('Greeter Components',() => {
it('renders correctly',() => {
var component = ReactTestUtils.renderIntoDocument(<div>
<Greeter name="Vamsi" place="Hotel California"/>
</div>);
var hasH1 = ReactTestUtils.findRenderedDOMComponentWithTag(component,'h1');
expect(hasH1).to.be.ok;
});
});
我收到错误
findAllInRenderedTree(...): instance must be a composite component.
我将我的代码提供为 jsbin here。
由于函数组件没有与之关联的实例,因此您不能直接将它们与 render 或 renderIntoDocument 一起使用。尝试包装函数组件是个好主意,不幸的是,由于类似的原因,使用 div
不起作用。 DOM 组件也不是 return 组件实例,而是 return 底层 DOM 节点。
这就是说您不能使用测试实用程序函数 或 本机组件作为您正在渲染的 "root" 组件。相反,您将希望将功能组件包装在使用 createClass
或扩展 React.Component
.
class Wrapper extends React.Component {
render() {
return this.props.children
}
}
let component = renderIntoDocument(<Wrapper><Greeter /></wrapper>
像这样的陷阱可能是充分利用第三方测试库的理由,比如流行的酶,或者我自己的看法:teaspoon。两者都通过为您无缝包装和展开功能组件来抽象此类问题,因此您无需担心要呈现的组件类型。
在 <div>
中包装功能组件对我有用。您只需要稍微不同地搜索要测试的组件,即
const props = { p1: "1" }
test('Foo renders correctly classed div', () => {
const cpt = TestUtils.renderIntoDocument(<div><Foo {...props} /></div>);
const myNode = ReactDOM.findDOMNode(cpt.childNodes[0]);
expect(myNode.className).toBe('my-class');
});
请注意,您可以使用 cpt.childNodes[0]
myNode
进行测试
为了改进@monastic-panic 的回答,我的两分钱:
您不必为此创建 class。动态执行:
import createReactClass from 'create-react-class';
// need to be a class component
const Clazz = createReactClass({
render: () => {
return <YourFunctionalComponentName {...props} />;
},
});
ReactTestUtils.renderIntoDocument(<Clazz />);