简体   繁体   中英

Jest wait for promise to resolve before finding an element

This is my sample code of React (the actual code resembles a lot to this but is too long to put here):

class Test extends Component {  
    state = {
        show: false
    }
    render() {
        return (
        <>
        {this.state.show && <div>Hello</div>}
        <button
            onClick={() => {

                //an ajax call to fetch data from server
                new Promise((resolve) => resolve(null)).then(() => {
                this.setState({show: true})
                })
            }}
        />
        </>
      )
    }
}

The jest test is below:

it('test', () => {
    const component = mount(< Test />);
    expect(component.find('div').length).toEqual(0); //passes

    component.find('button').prop<Function>('onClick')();
    expect(component.find('div').length).toEqual(1); //unstable response
})

Now the problem I am facing is that when I run this kind of tests where to find a component depends on a promise resolving, the tests are unstable. Some times they pass and sometime the component is not found.

The things that I have tried:

1- Using this sleep function:

const sleep = (milliseconds: number) => {
  return new Promise<number>(resolve => setTimeout(resolve, milliseconds));
};

And then use await sleep(1) after triggering a promise

2- Using this flush promises function:

const flushPromises = () => {
  return new Promise(resolve => setImmediate(resolve));
}

But I am unable to find the stability I want. The other thing this causes is if there are chained promises, then the test (mostly but not always hence unstable) exits before all the promises are resolved (which obviously cause the tests to fail). I have tried to increase timeout (third argument of it ) and use done callback, but of no use.

Can someone explain what am I doing wrong here and how the promise resolving works in jest test environment.

May be you could test the divs differently. Test for the div DOM is present or not by setting the state.

 component.setState({ show: true }); expect(component.find("div").length).toEqual(1);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM