Unit testing React如何使用setTimeout测试React component

Unit testing React如何使用setTimeout测试React component,unit-testing,reactjs,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

我遇到了这个测试问题,我不知道如何使用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>;
    }
}
import React,{PropTypes,Component}来自'React';
从“../../css/notification.css”导入样式;
导出默认类通知扩展组件{
静态类型={
tagMetaUpdate:PropTypes.shape({
submitUpdatedTagDataSuccessful:PropTypes.bool
}),
操作:PropTypes.shape({
resetUpdatedTagDataSuccessfulFlag:PropTypes.func
})
};
建造师(道具){
超级(道具);
此.state={
showMessage:正确
};
}
隐藏信息(动作){
this.timer=setTimeout(()=>{
this.state.showMessage=false;
actions.resetUpdatedTagDataSuccessfulFlag();
这个.forceUpdate();
}, 3000);
}
render(){
const{tagMetaUpdate,actions}=this.props;
常量输出=(tagMetaUpdate.submitUpdatedTagDataSuccessful&&this.state.showMessage)?
已成功编辑标记元数据。:null;
if(this.props.tagMetaUpdate.submitUpdatedTagDataSuccessful){
这个。隐藏信息(动作);//这是阻止我的一点
}否则{
this.state.showMessage=true;
}
返回{output};
}
}

直接改变状态通常是不明智的。尝试使用
this.setState({})
,当您调用setState时,这个.forceUpdate是不必要的。React将自行更新组件

此外,请尝试使用render方法仅执行渲染。没有变异状态等等

如果直接在render方法中执行
this.setState({showMessage:true})
,react会抱怨它-这是不允许的

React提供了一个生命周期钩子方法,称为
ComponentWillReceiveProps
componentWillUpdate
。您可以使用它们检查道具是否已更改,然后执行相应的设置状态

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将基于以下原因之一重新呈现组件:
    • 如果道具改变了
    • 如果组件的状态更新
    • 如果出于以下两个原因之一,其父级之一需要更新。 因此,我们要检查更新是否只是因为道具已更改而发生,如果已更改,则执行设置状态以显示消息,并设置超时以在3秒后不显示消息

这些只是使用建议。你能告诉我更多关于你用于单元测试的框架吗。如果这是开玩笑的话,我也许能帮上一点忙。

使用sinnon Faking time可以解决问题

滚动到伪造时间