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

如何在Jest中Mock同文件内的React组件?

解决同文件命名导出组件的Mock问题

看起来你在测试Modal组件时,想Mock同文件里的Item组件,但当前的jest.mock写法有几个问题导致没生效,我来帮你修正并解释原因:

你的现有写法问题分析

  1. jest.mock的第一个参数错误:你传了"Modal",但这个参数应该是模块的路径(也就是你的index.js文件路径),而不是组件名称。
  2. 废弃的API:require.requireActual已经被废弃,现在应该用jest.requireActual。
  3. 导出结构错误:你返回的对象把Modal重新赋值了,但实际上应该保留真实的Modal,只替换Item为Mock组件。

正确的Mock方案

方案一:使用jest.mock全局Mock模块

这种方式会在模块导入阶段就完成Mock,适合整个测试文件的所有用例:

// index.test.js
// 首先Mock当前模块
jest.mock('./index', () => {
  // 获取真实的模块导出内容
  const actualModule = jest.requireActual('./index');
  return {
    // 保留所有真实的导出,只替换需要Mock的Item
    ...actualModule,
    Item: jest.fn(() => <div>Mocked Item Component</div>)
  };
});

// 此时导入的Modal是真实组件,Item是Mock后的组件
import { Modal, Item } from './index';
import { render, screen } from '@testing-library/react';

test('Modal renders with mocked Item', () => {
  render(<Modal />);
  
  // 验证Item组件被调用
  expect(Item).toHaveBeenCalled();
  // 验证Modal中的Button是否正常渲染(可选)
  expect(screen.getByText('Great')).toBeInTheDocument();
});

方案二:使用jest.spyOn临时Mock

如果你只想在某个测试用例中MockItem,可以用jest.spyOn:

// index.test.js
import * as Components from './index';
import { render, screen } from '@testing-library/react';

test('Modal renders with temporarily mocked Item', () => {
  // 创建Mock的Item组件并替换原导出
  const mockItem = jest.spyOn(Components, 'Item')
    .mockImplementation(() => <div>Temporarily Mocked Item</div>);
  
  render(<Components.Modal />);
  
  // 验证Mock生效
  expect(mockItem).toHaveBeenCalled();
  expect(screen.getByText('Great')).toBeInTheDocument();
  
  // 测试结束后恢复原组件
  mockItem.mockRestore();
});

关键注意点

  • 因为你用的是命名导出,Mock时必须保持导出结构的一致性:要么展开真实模块的所有导出再替换目标组件,要么用spyOn精准替换单个导出。
  • 确保你的测试环境(比如Jest + React Testing Library)已经正确配置,能够识别JSX语法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:02:39