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

如何用react-testing-library和jest编写Promise reject场景的React单元测试

解决方案

你遇到的问题本质是异步断言时机不对,useEffect中的Promise回调属于异步微任务,直接在render后同步断言时catch逻辑还未执行,按以下步骤调整即可:

前置准备

确保你已经正确mock了ServiceComponent模块,示例如下:

// 替换为你实际的ServiceComponent导入路径
jest.mock('./service/ServiceComponent', () => ({
  get: jest.fn()
}))

完整测试代码

import { render, waitFor } from '@testing-library/react';
import Hotels from './Hotels';
import ServiceComponent from './service/ServiceComponent';

//  mock console.error 方便断言
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});

describe('Hotels 组件', () => {
  beforeEach(() => {
    jest.clearAllMocks();
  });

  it('请求失败时会调用 console.error 打印错误', async () => {
    // 注意mockRejectedValue要写在render之前
    const testError = new Error('request error');
    ServiceComponent.get.mockRejectedValue(testError);

    render(<Hotels />);

    // 等待异步逻辑执行完成后再断言
    await waitFor(() => {
      expect(ServiceComponent.get).toHaveBeenCalledWith('http://example.com');
      expect(consoleErrorSpy).toHaveBeenCalledWith(testError);
    });
  });
});

afterAll(() => {
  // 测试完成后恢复console.error的原始实现
  consoleErrorSpy.mockRestore();
});

常见排查点

  • 必须加await waitFor包裹异步断言,否则catch逻辑未执行就会执行断言语句
  • mockRejectedValue必须写在render方法之前,否则组件挂载执行useEffect时调用的还是未mock的原始方法
  • 确认ServiceComponent.get是静态方法,如果是实例方法需要调整mock逻辑适配你的导出写法

内容的提问来源于stack exchange,提问作者Kiran

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 00:48:01