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

如何在Jest中测试React Suspense的Axios Promise包装器

React Suspense 适配 useAxios Hook 的单元测试问题解决

问题背景

已实现适配React Suspense的useAxios Hook及promiseWrapper包装器,应用运行正常,但编写Jest单元测试时遇到两个问题:

  • 错误场景测试无法抛出预期错误
  • 不知如何模拟pending状态的行为

原错误场景测试代码:

it('should call endpoint and throw error on exception', async () => {
  mockedAxios.request.mockRejectedValueOnce(new Error('error'));

  expect(() => {
    renderHook(() => useAxios<TestResponseType>({}))
  }).toThrowError();
});

解决方案

1. 修复错误场景测试

原测试的核心问题:

  • useAxios返回的是promiseWrapper生成的函数,而非直接抛出错误,必须调用该函数才会触发错误抛出逻辑
  • 异步操作需要用async/await配合waitFor处理状态更新

修正后的测试代码:

import { renderHook, waitFor } from '@testing-library/react';

it('should throw error when request fails', async () => {
  mockedAxios.request.mockRejectedValueOnce(new Error('error'));

  const { result } = renderHook(() => useAxios<TestResponseType>({}));
  
  // 等待useEffect执行完成,response更新为包装函数
  await waitFor(() => expect(result.current).not.toBeNull());

  // 调用返回的函数,断言是否抛出预期错误
  expect(() => result.current()).toThrowError('error');
});

2. 模拟pending状态测试

要测试pending状态,需让Axios返回一个未决议的Promise,验证调用Hook返回的函数时会抛出该Promise:

it('should throw suspender promise when in pending state', async () => {
  // 创建一个始终处于pending状态的Promise
  const pendingPromise = new Promise(() => {});
  mockedAxios.request.mockReturnValueOnce(pendingPromise);

  const { result } = renderHook(() => useAxios<TestResponseType>({}));
  
  // 等待response被设置为包装函数
  await waitFor(() => expect(result.current).not.toBeNull());

  // 调用函数,断言抛出的是pending状态的Promise
  expect(() => result.current()).toThrow(pendingPromise);
});

关键说明

  • promiseWrapper返回的函数只有在被调用时,才会根据当前状态抛出Promise/错误或返回数据,测试时必须主动调用该函数
  • 需使用waitFor确保useEffect执行完成,response状态更新为包装函数后再进行断言

内容的提问来源于stack exchange,提问作者C A Mc

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 13:50:13