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

React+TypeScript单元测试引入axios时React-testing-library报错求助

问题

在React+TypeScript项目中编写单元测试时,引入axios并使用jest.mock("axios")模拟请求后,运行测试出现报错。已尝试安装axios类型定义、配置Babel、在package.json中添加--transformIgnorePatterns "node_modules/(?!axios)/"配置,但问题仍未解决。

组件代码:

import axios from "axios";
import React, { FC, useEffect, useState } from "react";
import { IUser } from "../../types/IUsers";

const Users: FC = () => {
  const [users, setUsers] = useState<IUser[]>([]);
  useEffect(() => {
    getUsers();
  }, [users]);

  const getUsers = async () => {
    try {
      const response = await axios.get(
        "https://jsonplaceholder.typicode.com/users/"
      );
      const res = response.data;
      setUsers(res);
    } catch (error) {
      console.log(error);
    }
  };
  return (
    <div data-testid="users-wrapper">
      {users.map((user) => (
        <div>{user.name}</div>
      ))}
    </div>
  );
};

export default Users;

测试代码:

import React from "react";
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import Users from "./Users";
import axios from "axios";

jest.mock("axios");
describe("Testing user component", () => {
  test("Show title", () => {
    render(<Users />);
    const usersWrapper = screen.getByTestId("users-wrapper");
    expect(usersWrapper).toBeInTheDocument();
  });
});
解决方案

1. 修复组件内的无限循环问题

你的useEffect依赖了users状态,每次调用setUsers更新状态时,都会重新触发useEffect调用getUsers,形成无限循环,这会导致测试超时或报错。修改useEffect的依赖项为空数组,确保只在组件挂载时执行一次:

useEffect(() => {
  getUsers();
}, []); // 移除users依赖

如果需要后续重新触发请求,可以将getUsers用useCallback包裹,按需添加依赖。

2. 正确配置axios的Mock类型与返回值

由于使用TypeScript,jest.mock("axios")生成的Mock对象需要明确类型,同时要模拟axios.get的返回值,避免测试中出现异步请求未处理的问题:

import React from "react";
import { render, screen } from "@testing-library/react";
import Users from "./Users";
import axios from "axios";

// 类型断言,告知TypeScript这是被Jest Mock的axios实例
const mockedAxios = axios as jest.Mocked<typeof axios>;

describe("Testing user component", () => {
  // 每次测试前重置Mock,避免测试间的状态污染
  beforeEach(() => {
    mockedAxios.get.mockReset();
  });

  test("Renders users wrapper and loads users", async () => {
    // 模拟axios.get的成功返回数据
    mockedAxios.get.mockResolvedValue({
      data: [{ id: 1, name: "Test User 1" }, { id: 2, name: "Test User 2" }]
    });

    render(<Users />);

    // 等待异步请求完成并渲染用户列表
    await screen.findByText("Test User 1");

    const usersWrapper = screen.getByTestId("users-wrapper");
    expect(usersWrapper).toBeInTheDocument();
    // 验证axios.get被正确调用
    expect(mockedAxios.get).toHaveBeenCalledTimes(1);
    expect(mockedAxios.get).toHaveBeenCalledWith("https://jsonplaceholder.typicode.com/users/");
  });
});

3. 确保Jest正确转换axios模块

如果使用Create React App,需要在package.json的scripts中正确配置transformIgnorePatterns,注意转义引号:

{
  "scripts": {
    "test": "react-scripts test --transformIgnorePatterns \"node_modules/(?!axios)/\""
  }
}

如果是自定义Jest配置(jest.config.js),添加以下配置:

module.exports = {
  transform: {
    "^.+\\.(ts|tsx)$": "ts-jest",
    "^.+\\.(js|jsx)$": "babel-jest",
  },
  transformIgnorePatterns: [
    "node_modules/(?!axios)/"
  ],
};

4. 确认类型依赖匹配

确保@types/axios的版本与安装的axios版本匹配,避免类型冲突:

npm install @types/axios@匹配axios的版本号 --save-dev

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 15:51:52