如何测试React Loadable组件?附组件及测试代码示例
测试React Loadable异步组件的完整方案
要测试你用React Loadable实现的异步组件,核心是要处理组件加载中的状态和加载完成后的渲染状态,下面我会基于@testing-library/react(目前React测试的主流工具)来一步步补全你的测试代码:
1. 准备测试依赖
首先确保你已经安装了必要的测试包:
npm install --save-dev @testing-library/react @testing-library/jest-dom
2. 测试加载中的状态
当组件还在异步加载Upload组件时,应该显示你定义的LoadingComponent。我们可以通过mockReact Loadable的加载过程来模拟这个状态:
import React from 'react'; import { render, screen } from '@testing-library/react'; import Component from './index'; import Loadable from 'react-loadable'; // Mock React Loadable,让它停留在加载状态 jest.mock('react-loadable', () => ({ __esModule: true, default: (options) => { // 返回一个始终处于加载状态的组件 return () => options.loading({ full: true }); }, })); describe('Component', () => { it('should display loading component while Upload is loading', () => { render(<Component />); // 假设你的LoadingComponent有可识别的文本或属性,比如包含"Loading..."文本 expect(screen.getByText(/Loading.../i)).toBeInTheDocument(); }); });
3. 测试加载完成后的状态
接下来要测试异步组件加载完成后,是否正确渲染了Upload组件。这里需要mockUpload组件,并让React Loadable完成加载:
import React from 'react'; import { render, screen, waitFor } from '@testing-library/react'; import Component from './index'; import Loadable from 'react-loadable'; // 先mock Upload组件 jest.mock('components/Upload', () => ({ __esModule: true, default: () => <div data-testid="upload-component">Upload Component</div>, })); // 重新mock Loadable,让它能完成加载 jest.mock('react-loadable', () => ({ __esModule: true, default: (options) => { // 创建一个组件,模拟加载完成的状态 return () => { const [loaded, setLoaded] = React.useState(false); React.useEffect(() => { options.loader().then(() => setLoaded(true)); }, []); return loaded ? React.createElement(require('components/Upload').default) : options.loading({ full: true }); }; }, })); describe('Component', () => { it('should render Upload component after loading completes', async () => { render(<Component />); // 等待Upload组件加载完成并渲染 await waitFor(() => { expect(screen.getByTestId('upload-component')).toBeInTheDocument(); }); // 同时验证加载组件已经消失 expect(screen.queryByText(/Loading.../i)).not.toBeInTheDocument(); }); });
4. 如果你使用Enzyme(旧项目常用)
如果你的项目还在使用Enzyme,也可以这样实现测试:
import React from 'react'; import { shallow, mount } from 'enzyme'; import Component from './index'; import Loadable from 'react-loadable'; import LoadingComponent from 'path-to-your-loading-component'; import Upload from 'components/Upload'; jest.mock('react-loadable'); describe('Component', () => { beforeEach(() => { jest.clearAllMocks(); }); it('renders LoadingComponent initially', () => { // 模拟加载中状态 Loadable.mockImplementation(() => () => <LoadingComponent full />); const wrapper = shallow(<Component />); expect(wrapper.find(LoadingComponent)).toHaveLength(1); }); it('renders Upload component after loading', async () => { // 模拟加载完成 Loadable.mockImplementation(() => { return class MockLoadable extends React.Component { state = { loaded: false }; componentDidMount() { import('components/Upload').then(() => this.setState({ loaded: true })); } render() { return this.state.loaded ? <Upload /> : <LoadingComponent full />; } }; }); const wrapper = mount(<Component />); await new Promise(resolve => setImmediate(resolve)); wrapper.update(); expect(wrapper.find(Upload)).toHaveLength(1); expect(wrapper.find(LoadingComponent)).toHaveLength(0); }); });
关键注意点
- 一定要mock异步加载的过程,避免测试中真的去加载组件文件,保证测试的速度和稳定性。
- 使用
waitFor(testing-library)或setImmediate+update(Enzyme)来等待异步操作完成,确保组件渲染完成后再做断言。 - 给测试的组件添加
data-testid是个好习惯,让测试更稳定,不受文本内容变化的影响。
内容的提问来源于stack exchange,提问作者Albert Olivé Corbella
相关产品推荐
相关产品推荐

