我正在尝试测试具有异步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.
解决方案:
- 如何使用Jest测试异步组件?
- github/airbnb/enzyme/issues/1027
- github/airbnb/enzyme/issues/1581
- github/airbnb/enzyme/issues/346
- How do test async components with Jest?
- github/airbnb/enzyme/issues/1027
- github/airbnb/enzyme/issues/1581
- github/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.prototypeponentDidMount).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:']) }) }) })这是componentDidMount和filterResults的实现(前者称为):
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
发布评论