I'm trying to test a React component which has an async componentDidMount.
The promise itself doesn't need to be mocked, it's not necessarily for accessing outer content, mostly just a wrapper for props.
However, in order to test it I need to use wrapper.update() 4 times which seems really weird to me.
The solutions in:
- How do test async components with Jest?
- https://github.com/airbnb/enzyme/issues/1027
- https://github.com/airbnb/enzyme/issues/1581
- https://github.com/airbnb/enzyme/issues/346
all didn't work for me.
Here's what my test looks like (which currently works, but this solution isn't elegant at all, and not too scalable):
import * as React from 'react'
import { shallow, mount } from 'enzyme'
import LargeSelector from './LargeSelector'
describe('<LargeSelector />', async () => {
    const componentDidMountSpy = jest.spyOn(LargeSelector.prototype, 'componentDidMount')
    describe('search', async () => {
        it('should save initial response in cache', async () => {
            const wrapper = await shallow(<LargeSelector query={async (search) => ['search:' + search]} />)
            // WHY DO I NEED 4 UPDATES???
            await wrapper.update()
            await wrapper.update()
            await wrapper.update()
            await wrapper.update()
            expect(LargeSelector.prototype.componentDidMount).toHaveBeenCalledTimes(1) // works fine
            // these 2 only pass the expectation if I call wrapper.update() no less than 4 times    
            expect(wrapper.state()).toHaveProperty('options', ['search:'])
            expect(wrapper.state()).toHaveProperty('initialOptions', ['search:'])
        })
    })
})
Here are the implementations of componentDidMount and filterResults (call in the former):
public async componentDidMount() {
    if (this.props.searchOnInit) {
        const results = await this.filterResults('', [])
        if (this.props.cacheInitialResponse) {
            this.setState({ initialOptions: results })
        }
    }
}
private async filterResults(search: string, filters: IFilter[]) {
    const results = await this.props.query(search, filters)
    this.setState({ options: results })
    return results
}
 
     
     
     
     
     
    