通过ajax调用在componentDidMount中正确设置测试状态

时间:2015-09-11 23:22:01

标签: javascript asynchronous reactjs jasmine promise

我的反应组件中有以下代码

componentDidMount() {

    ajax.call().then((data)=> {

        this.setState({a:data.a});
    });
}

我正在简单地调用一个返回promise的函数。

当我尝试测试从已解决的promise中正确设置状态时,我的测试看起来像这样。

        it('should set state of a', (done)=> {

            let ajax = {
                call: ()=>{}
            };

            spyOn(ajax, 'call').and.returnValue(Promise.resolve({a:'a'}));

            let component = TestUtils.renderIntoDocument(<MyComp/>);

            expect(component.state.a).toEqual('a');
        });

我很确定状态实际上是从承诺返回的数据中设置的,但问题是我无处可称为茉莉花&#39;完成()&#39;函数告诉jasmine异步操作已经完成,并且可以测试状态上的断言。

1 个答案:

答案 0 :(得分:2)

React社区大多同意通过更好地管理州 “好像'它同步出现,所以它可以被快照。这给了我们视图作为单个状态变量的函数,并使我们的代码易于测试。如果你没有投资建筑 - 我建议你尝试FLUX像架构并查看常见的库,如redux和este。

也就是说,像你一样在AJAX之后显式设置组件的状态是完全没问题的。我将测试分成两部分:

  • 将一个state变量设置为AJAX的返回值,您只需检查对象是否已更改即可对此进行测试。
  • 致电render重新渲染您正在测试的组件(而不是setState)。

然后,您可以测试渲染和承诺设置状态的不同使得渲染测试易于推理(它们是同步的)和AJAX测试很容易(它只是对象)。

一般情况下,当您使用mocha测试promise时,您可以使用专用的promise语法,因为您正在使用React,无论如何您都在使用Babel,因此您可以在代码中使用新的JavaScript功能:

it('does ajax', async function(){ // can also `async () =>`
    var result = await ajax.call(); // call the ajax, get response, can be mocked
    var state = result;
    var str = React.renderToString(<MyComp prop={result} />);
    // assert against the returned HTML, can also test against DOM
});