如何用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
相关产品推荐
相关产品推荐

