You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何测试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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 11:06:09