反应测试; 如何模拟componentDidMount或覆盖它?

Bes*_*haj 12 testing unit-testing mocking reactjs

我正在尝试测试反应组件.

var Component = React.createClass({

  componentDidMount: function () {

    return this.setState({
      name: 'blabla'
    });
  },

  render: function () {

    return (
      <h1>{this.state.name}</h1>
    );
  }
});
Run Code Online (Sandbox Code Playgroud)

在测试过程中,有没有办法模拟componentDidMount返回或做什么?这将让我自己测试它,只测试组件渲染行为.

谢谢!

Cat*_*che 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(...)
    });
});
Run Code Online (Sandbox Code Playgroud)

重点是创建一个随需应变的ChildClass继承OriginalClass,做任何覆盖然后再做 TestUtils.renderIntoDocument(<ChildClass />)


Mic*_*ker 2

如果我理解正确的话,这里的想法是,您试图在测试中渲染组件之前删除一个函数。在您的情况下,componentWillMount仅在组件的生命周期中调用一次,即在渲染组件之前调用。所以你不能只渲染组件然后将函数存根,它必须在渲染发生之前完成。

我们以这些组件为例:

父.js

var Child = require('./child.js');
var Parent = React.createClass({
    render : function () {
        return (
            <div className="parent">
                <Child/>
            </div>
        );
    }
});
module.exports = Parent;
Run Code Online (Sandbox Code Playgroud)

孩子.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;
Run Code Online (Sandbox Code Playgroud)

在这里,我们想要删除test在这里,我们希望在渲染子组件之前

我已经能够使用jasmine-react来做到这一点。这些辅助函数在运行测试时提供了一些有用的功能,几乎达到了这样的程度:TestUtils可以完全放弃。

jasmineReact.render(component, [container])将把 的实例渲染component到 中指定的 DOM 节点中[container]。这就像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
    });
});
Run Code Online (Sandbox Code Playgroud)

如果您有任何疑问,请告诉我。