React使用Jest mock axios测试异步组件不生效排查
问题排查结果
核心错误有2个,直接导致元素无法渲染:
- axios mock返回结构不符合预期
组件代码中通过response.data读取接口返回的加密货币列表,但当前mock的axios.get直接resolve了数组本身,导致response.data为undefined,组件执行setCryptoFeed([])逻辑,列表为空自然找不到Bitcoin文本。 - mock数据字段和组件读取字段不匹配
组件渲染PriceBlock时读取的字段是current_price、total_volume、price_change_24h,但mock数据中定义的字段是price、volume、change,就算返回结构修复,后续props传值也会异常。
额外隐患:组件设置了1秒间隔的轮询定时器,测试环境下不处理会导致定时器堆积,引发用例超时、内存泄漏问题。
修复方案
1. 修正axios mock实现
调整返回结构对齐真实axios响应格式,同时修正字段名和组件使用的字段保持一致:
// src/__mocks__/axios.js const mockCryptoList = [ { id: "bitcoin", name: "Bitcoin", current_price: 20000, total_volume: 12004041094, price_change_24h: -12241, }, { id: "solana", name: "Solana", current_price: 87, total_volume: 200876648, price_change_24h: 122, }, ]; export default { get: jest.fn().mockResolvedValue({ data: mockCryptoList }), };
2. 优化测试用例,处理定时器
使用Jest fake timer接管轮询逻辑,避免定时器干扰测试执行:
import { render, screen } from "@testing-library/react"; import RealtimePrice from "../RealtimePrice"; describe("Realtime Price", () => { beforeEach(() => { jest.useFakeTimers(); }); afterEach(() => { jest.runOnlyPendingTimers(); jest.useRealTimers(); jest.clearAllMocks(); }); it("should render the Bitcoin price block", async () => { render(<RealtimePrice />); const bitcoinBlock = await screen.findByText("Bitcoin"); expect(bitcoinBlock).toBeInTheDocument(); }); });
若使用React 18版本,需确认测试环境已配置
@testing-library/reactv13+版本适配React 18的并发渲染逻辑,否则异步状态更新可能不会触发DOM重渲染。
内容的提问来源于stack exchange,提问作者Stephen Fong
相关产品推荐
相关产品推荐

