React + Jest-测试异步组件并等待挂载 [英] React+Jest - Testing async components and waiting for mount

查看:207
本文介绍了React + Jest-测试异步组件并等待挂载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试测试具有异步componentDidMount的React组件.

I'm trying to test a React component which has an async componentDidMount.

promise本身不必被嘲笑,它不一定用于访问外部内容,主要只是用于道具的包装.

The promise itself doesn't need to be mocked, it's not necessarily for accessing outer content, mostly just a wrapper for props.

但是,要进行测试,我需要使用wrapper.update() 4次,这对我来说真的很奇怪.

However, in order to test it I need to use wrapper.update() 4 times which seems really weird to me.

解决方案:

  • 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

一切都不适合我.

这是我的测试的样子(目前可以使用,但是此解决方案一点也不优雅,并且扩展性也不太好):

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:'])
        })
    })
})

这是componentDidMountfilterResults的实现(前者称为):

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
}

推荐答案

我遇到了完全相同的问题. 问题在于测试不会等待承诺实现.我的解决方案是使用Jest提供的done回调作为测试结束的信号.

I was facing the exact same problem. The problem is that the test won't wait for the promises to be fulfilled. My solution was to use the the done callback, provided by Jest, as a signal of the test ended.

赞:

it('wait async code before assert something', (doneCallback) => {
    const wrapper = shallow(<Component />);

    setImediate(() => {
        expect(wrapper.find('.async').length).toBe(1);
        doneCallback();
    });
});

这篇关于React + Jest-测试异步组件并等待挂载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆