我正在尝试测试反应组件。
var Component = React.createClass({
componentDidMount: function () {
return this.setState({
name: 'blabla'
});
},
render: function () {
return (
<h1>{this.state.name}</h1>
);
}
});
在测试过程中,有没有办法模拟componentDidMount
返回或做什么?这将让我自己测试它,只测试组件渲染行为。
谢谢!
答案 0 :(得分:6)
我更喜欢以下方法,但需要使用ES6类。
// component.jsx
class Component extends React.Component {
componentDidMount() { return this.setState({name: 'blabla'}); }
render() { return (<h1>{this.state.name}</h1>); }
}
//component-spec.jsx
describe('Component', () => {
it('does stuff', () => {
let ComponentTest = class extends Component {
componentDidMount() {
// your override here
}
};
let component = TestUtils.renderIntoDocument(<ComponentTest />);
//expect(component...).toEqual(...)
});
});
重点是创建一个继承OriginalClass的按需ChildClass,
做任何覆盖,然后TestUtils.renderIntoDocument(<ChildClass />)
答案 1 :(得分:2)
如果我理解正确的话,这里的想法是你在测试中呈现组件之前尝试存根函数。在您的情况下,componentWillMount
仅在组件的生命周期中被调用一次,紧接在呈现组件之前。所以你不能只渲染组件而然后存根该函数,它必须在渲染发生之前完成。
我们以这些组件为例:
<强> parent.js 强>
var Child = require('./child.js');
var Parent = React.createClass({
render : function () {
return (
<div className="parent">
<Child/>
</div>
);
}
});
module.exports = Parent;
<强> child.js 强>
var Child = React.createClass({
test : function () {
return true;
},
render : function () {
if (this.test) {
throw('boom');
}
return (
<div className="child">
Child
</div>
);
}
});
module.exports = Child;
在这里,我们希望在呈现Child组件之前存根test
函数,否则它会爆炸。
我可以使用jasmine-react执行此操作。这些辅助函数在运行测试时提供了一些有用的功能,几乎到了TestUtils
可以完全抛弃的程度。
jasmineReact.render(component, [container])
会将component
的实例呈现到[container]
中指定的DOM节点中。这类似于TestUtils.renderIntoDocument()
,除了它将组件呈现为附加的DOM节点而不是分离的DOM节点。测试完成后,它还将执行必要的清洁操作。
jasmineReact.spyOnClass(componentClass, functionName)
将存根属于组件类的特定函数。此行为一直持续到测试结束,这意味着您可以在呈现组件之前调用此函数。如果我理解正确的话,这就是你要找的东西。
所以,使用这两个辅助函数,我可以为上面显示的代码编写一个测试,看起来像这样:
var React = require('react/addons'),
Parent = require('./parent.js'),
Child = require('./child.js'),
jasmineReact = require('jasmine-react-helpers');
describe('Parent', function () {
it('does not blow up when rendering', function () {
jasmineReact.spyOnClass(Child, 'test').and.returnValue(false);
var parentInstance = jasmineReact.render(<Parent/>, document.body); //does not blow up
expect(parentInstance).toBeTruthy(); //passes
});
});
如果您有任何问题,请与我们联系。
答案 2 :(得分:1)
我发现了两种方法(我相信还有更多)。
1)我在基本元素类中使用了sinon-chai并且必需,然后使用rewireify在componentWillMount
方法上设置一个间谍集。这有效,但不确定您正在使用哪些测试套件。
2)可能更简单的方法。只是使用TestUtils获取组件的实例,然后只需手动运行componentWillMount
方法。
第二种方式可能看起来像(原谅pesudo代码):
it('should call state when it first mounts', function () {
var Component = require('../my-component');
var component = TestUtils.renderIntoDocument(<Component />);
component.setState({name: null});
component.componentWillMount();
expect(component.state.name).to.equal('blabla');
});