用setTimeout反应如何测试反应组合

时间:2016-02-13 11:05:40

标签: unit-testing reactjs

我遇到了这个测试问题,我不知道如何用 settimeout 测试组件。有人建议如何使用 settimeout 测试以下组件?非常感谢

import React, { PropTypes, Component } from 'react';
import styles from '../../../css/notification.css';

export default class Notification extends Component {
    static propTypes = {
        tagMetaUpdate: PropTypes.shape({
            submitUpdatedTagDataSuccessful: PropTypes.bool
        }),
        actions: PropTypes.shape({
            resetUpdatedTagDataSuccessfulFlag: PropTypes.func
        })
    };

    constructor(props) {
        super(props);
        this.state = {
            showMessage: true
        };
    }

    hideMessage(actions) {
        this.timer = setTimeout(() => {
            this.state.showMessage = false;
            actions.resetUpdatedTagDataSuccessfulFlag();
            this.forceUpdate();
        }, 3000);
    }

    render() {
        const { tagMetaUpdate, actions } = this.props;
        const output = (tagMetaUpdate.submitUpdatedTagDataSuccessful && this.state.showMessage) ?
            <div className={styles.notification}>Tag meta data successfully edited.</div> : null;

        if (this.props.tagMetaUpdate.submitUpdatedTagDataSuccessful) {
            this.hideMessage(actions); // HERE IS THE BIT BLOCKING ME
        }else {
            this.state.showMessage = true;
        }

        return <div>{output}</div>;
    }
}

2 个答案:

答案 0 :(得分:2)

使用sinnon伪造时间将解决问题

http://sinonjs.org/

滚动到假冒时间

答案 1 :(得分:1)

直接改变国家通常是不明智的。尝试使用this.setState({}),当您调用setState时,不需要this.forceUpdate。 React会自行更新您的组件。

此外,尝试使用render方法仅执行渲染。没有变异的状态和所有这些。

如果您直接在渲染方法中执行this.setState({ showMessage: true }),则会抱怨它 - 它是不允许的。

React提供了一个名为componentWillRecievePropscomponentWillUpdate的生命周期钩子方法。您可以使用它们检查道具是否已更改,然后相应地执行setState。

componentWillReceiveProps(nextProps){
  if(!_.isEqual(nextProps, this.props) {
    if(nextProps.tagMetaUpdate.submitUpdatedTagDataSuccessful){
      this.setState({ showMessage: true })
      this.timer = setTimeout(() => {
        this.setState({ showMessage: false })
        actions.resetUpdatedTagDataSuccessfulFlag()
      }, 3000)
    }
  }
}

请注意:

  • 通过在setTimeout中使用setState,我已经不再需要使用forceUpdate()
  • 我使用lodash进行检查以查看道具是否已从之前的渲染更改为当前渲染。由于以下原因之一,React会重新渲染组件:
    • 如果道具改变
    • 如果组件的状态更新
    • 如果其中一位父母需要更新,原因有两个。 因此,我们检查是否发生了更新,因为prop已更改,如果已更改,则执行setState以显示消息,并设置超时以在3秒后不显示消息。

这些只是用法建议。你能告诉我更多关于你用于单元测试的框架吗?如果它开玩笑,我可以帮助一下。