使用异步工作验证React Native组件

时间:2018-01-07 21:07:26

标签: react-native jest

我有一个在componentDidMount阶段调用web服务的基本组件,并覆盖了我的状态中的contents值:

import React, {Component} from 'react';
import {Text} from "react-native";

class Widget extends Component {

    constructor() {
        super();
        this.state = {
            contents: 'Loading...'
        }
    }

    async componentDidMount() {
        this.setState(...this.state, {
            contents: await this.getSomeContent()
        });
    }

    render() {
        return (
            <Text>{this.state.contents}</Text>
        )
    }

    async getSomeContent() {
        try {
            return await (await fetch("http://someurl.com")).text()
        } catch (error) {
            return "There was an error";
        }
    }
}

export default Widget;

我想在以下每种情况下使用Jest快照捕获组件的状态:

  • 装载
  • 成功
  • 错误

问题在于我必须引入片状暂停来验证组件的状态。

例如,要查看成功状态,您必须在渲染组件后稍微停顿一下,以便让setState方法有机会赶上:

test('loading state', async () => {

    fetchMock.get('*', 'Some Content');
    let widget = renderer.create(<Widget />);

    // --- Pause Here ---
    await new Promise(resolve => setTimeout(resolve, 100));

    expect(widget.toJSON()).toMatchSnapshot();
});

我正在寻找克服测试用例中异步性的最佳方法,以便我能够正确验证每个州的快照。

1 个答案:

答案 0 :(得分:0)

如果您将异步呼叫移出setState,则可以延迟setState,直到网络呼叫解决。然后你可以使用setState's可选回调(在状态改变后触发)来捕获状态。

所以,像这样:

async componentDidMount() {
 var result = await this.getSomeContent()
 this.setState(...this.state, {
     contents: result
 },
 // setState callback- fires when state changes are complete.
 ()=>expect(this.toJSON()).toMatchSnapshot()
 );
}

更新:

如果要在组件外部指定验证,可以创建一个prop,例如stateValidation来传递验证函数:

jest('loading state', async () => {

    fetchMock.get('*', 'Some Content');

    jestValidation = () => expect(widget.toJSON()).toMatchSnapshot();

    let widget = renderer.create(<Widget stateValidaton={jestValidation}/>); 

});

然后在组件中使用prop:

async componentDidMount() {
 var result = await this.getSomeContent()
 this.setState(...this.state, {
     contents: result
 },
 // setState callback- fires when state changes are complete.
 this.props.stateValidaton
 );
}