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

如何使用React Testing Library正确测试经React Router传参的EditPage组件

测试方案说明

前置准备

首先你需要做两个核心模拟:

  • 模拟axios库,拦截请求避免调用真实接口,同时可以验证请求参数
  • 给组件传递正确的路由参数,保证useParams可以拿到初始的用户数据

注意请将测试代码里的路由path替换为你项目中实际配置的EditPage访问路径

完整测试代码

import { render, screen, fireEvent } from '@testing-library/react';
import { MemoryRouter, Routes, Route } from 'react-router-dom';
import axios from 'axios';
import EditPage from './EditPage';

// 全局模拟axios
jest.mock('axios');

// 模拟的初始用户参数
const mockUserParams = {
  id: '123',
  name: '初始姓名',
  email: 'initial@test.com',
  status: 'active'
};

const setup = () => {
  render(
    <MemoryRouter initialEntries={[`/edit/${mockUserParams.id}/${mockUserParams.name}/${mockUserParams.email}/${mockUserParams.status}`]}>
      <Routes>
        <Route path="/edit/:id/:name/:email/:status" element={<EditPage />} />
        {/* 模拟跳转目标路由 */}
        <Route path="/users" element={<div>用户列表页</div>} />
      </Routes>
    </MemoryRouter>
  );
  // 清空之前的调用记录,避免测试用例互相影响
  axios.put.mockClear();
};

describe("edit page", () => {
  test("renders properly with initial user data", () => {
    setup();
    expect(screen.getByTestId("editpage-title")).toBeInTheDocument();
    expect(screen.getByTestId("editpage-inputs")).toBeInTheDocument();
    expect(screen.getByTestId("editpage-buttons")).toBeInTheDocument();
    // 验证初始值正确填充
    expect(screen.getByPlaceholderText("Insert the name...")).toHaveValue(mockUserParams.name);
    expect(screen.getByPlaceholderText("Insert the email...")).toHaveValue(mockUserParams.email);
    expect(screen.getByRole('combobox')).toHaveValue(mockUserParams.status);
  });

  test("changing values of inputs works correctly", () => {
    setup();
    const nameInput = screen.getByPlaceholderText("Insert the name...");
    const emailInput = screen.getByPlaceholderText("Insert the email...");
    const statusSelect = screen.getByRole('combobox');

    fireEvent.change(nameInput, { target: { value: "测试姓名" } });
    fireEvent.change(emailInput, { target: { value: "test@test.com" } });
    fireEvent.change(statusSelect, { target: { value: "inactive" } });

    expect(nameInput).toHaveValue("测试姓名");
    expect(emailInput).toHaveValue("test@test.com");
    expect(statusSelect).toHaveValue("inactive");
  });

  test("click UPDATE button sends correct put request and jumps to user list", async () => {
    setup();
    const nameInput = screen.getByPlaceholderText("Insert the name...");
    const emailInput = screen.getByPlaceholderText("Insert the email...");
    const statusSelect = screen.getByRole('combobox');
    const updateBtn = screen.getByTestId("editpage-updatebutton");

    // 修改输入值
    fireEvent.change(nameInput, { target: { value: "测试姓名" } });
    fireEvent.change(emailInput, { target: { value: "test@test.com" } });
    fireEvent.change(statusSelect, { target: { value: "inactive" } });

    // 点击更新按钮
    fireEvent.click(updateBtn);

    // 验证axios.put被正确调用
    expect(axios.put).toHaveBeenCalledTimes(1);
    expect(axios.put).toHaveBeenCalledWith(
      `https://gorest.co.in/public/v1/users/${mockUserParams.id}`,
      {
        name: "测试姓名",
        email: "test@test.com",
        status: "inactive"
      },
      expect.objectContaining({
        headers: expect.objectContaining({
          Authorization: expect.stringContaining("Bearer ")
        })
      })
    );

    // 验证跳转到用户列表页
    expect(await screen.findByText("用户列表页")).toBeInTheDocument();
  });

  test("click CANCEL button does not send request and jumps to user list", async () => {
    setup();
    const cancelBtn = screen.getByText("CANCEL");

    // 点击取消按钮
    fireEvent.click(cancelBtn);

    // 验证没有发送更新请求
    expect(axios.put).not.toHaveBeenCalled();

    // 验证跳转到用户列表页
    expect(await screen.findByText("用户列表页")).toBeInTheDocument();
  });
});

关键逻辑说明

  • 用MemoryRouter配置初始路由参数,模拟真实的跳转场景,保证useParams能拿到正确的初始用户数据
  • 全局模拟axios后,通过mockClear清空每次测试的调用记录,避免用例互相干扰
  • 更新按钮的测试中,验证axios.put的调用参数、请求地址、请求头是否符合预期,就能确认数据是否正确提交
  • 取消按钮的测试中,验证axios.put没有被调用,就能确认没有触发数据更新逻辑
  • 最后通过查找跳转后的页面内容,验证路由跳转逻辑正常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 12:57:01