测试componentDidMount中setTimeout的执行情况?

时间:2017-01-04 19:12:19

标签: reactjs jestjs enzyme

我有以下组件:

class PlayButton extends Component {
    constructor () {
        super();

        this.state = { glow: false };
        this.play = this.play.bind(this);
    }
componentDidUpdate () {
        if (this.props.media.currentTime === 0 && this.props.media.duration !== 0 && !this.state.glow) {
            console.log('entering')
            setTimeout(() => {
                console.log('did time out')
                this.setState({ glow: true });
            }, 3000);
        }

        if (this.props.media.currentTime !== 0 && this.state.glow) {
            this.setState({ glow: false });
        }
    }

我想测试componentDidMount中的setState但是无法完成它:

it('button shoould start glowing', () => {
        const wrapper = mount(<PlayButton media={{ currentTime: 0, duration: 1 }}/>);
        wrapper.update()
        jest.runAllTimers();
        expect(wrapper.state('glow')).toBe(true);
    });

有什么想法? 谢谢!

3 个答案:

答案 0 :(得分:1)

好吧,这就是我解决它的方式:

it('button shoould start glowing', () => {
        let clock = sinon.useFakeTimers();
        const wrapper = mount(<PlayButton media={{ currentTime: 0, duration: 1 }}/>);
        wrapper.update()
        clock.tick(3000)
        expect(wrapper.state('glow')).toBe(true);
    });

答案 1 :(得分:0)

您可以传入setTimeout的模拟,而不是立即调用回调:

static defaultProps = {
    timeout: setTimeout
}
this.props.timeout(() => {
    console.log('did time out')
    this.setState({ glow: true });
}, 3000);
it('button shoould start glowing', () => {
    const wrapper = mount(<PlayButton media={{ currentTime: 0, duration: 1 }} 
                               timeout={(fn, _) => fn()}}/>);
    wrapper.update()
    jest.runAllTimers();
    expect(wrapper.state('glow')).toBe(true);
});

答案 2 :(得分:0)

调用runAllTimers后,您必须更新包装器。 查看这篇文章,对我来说https://medium.com/@DavideRama/testing-async-setstate-in-react-settimeout-in-componentdidmount-434602abd7db

const items = ['die Straße', 'die Adresse', 'die Nationalität'];

jest.useFakeTimers();

describe('<DelayedList />', () => {
  test('it renders the items with delay', () => {
    const component = shallow(
      <DelayedList items={items} />
    );

    jest.runAllTimers();
    component.update(); // <--- force re-render of the component

    expect(component.state().currentIndex).toEqual(items.length);
    expect(component).toMatchSnapshot();
  });
});