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

Vitest跨测试文件复用MUI组件Mock方案求助

解决Vitest中复用MUI公共Mock的问题

问题核心原因

你遇到的错误是因为Vitest的vi.mock会被自动提升到文件顶层执行,此时你导入的mockedLibrary变量还未完成初始化,导致工厂函数无法找到该变量。另外,vi.mock是模块级别的操作,必须在文件顶层调用,不能放在beforeEach这类测试钩子中。

解决方案

下面提供两种可复用Mock的实现方式,均能避免重复编写Mock代码,同时避开vi.importActual带来的性能问题:


方案1:使用Vitest自动Mock目录(推荐)

Vitest会自动识别项目根目录下__mocks__文件夹中的文件,匹配对应模块名实现自动Mock,无需在每个测试文件中重复编写Mock逻辑。

  1. 创建Mock文件
    在项目根目录新建__mocks__/@mui/material.jsx(路径需与模块名严格对应):
import vi from 'vitest';

// 只Mock需要用到的组件,避免全量导入提升速度
export const Button = vi.fn().mockImplementation((props) => (
  <button className="mockedButton" {...props} />
));

// 可按需添加其他MUI组件的Mock
// export const TextField = vi.fn().mockImplementation((props) => <input className="mockedInput" {...props} />);
  1. 在测试文件中启用Mock
    只需在测试文件顶层调用vi.mock,Vitest会自动加载__mocks__中的配置:
// 顶层调用,自动复用公共Mock
vi.mock('@mui/material');

import { render, screen } from '@testing-library/react';
import App from './App';

describe("App tests", () => {
  beforeEach(() => {
    // 每次测试前重置Mock状态,避免跨测试污染
    vi.clearAllMocks();
  });

  it('渲染Mock按钮', () => {
    render(<App />);
    expect(screen.getByText('Test')).toBeInTheDocument();
    expect(screen.getByRole('button')).toHaveClass('mockedButton');
  });
});

方案2:创建公共Mock工厂函数

如果不想依赖自动Mock目录,可以编写一个返回Mock对象的公共函数,确保vi.mock提升后能正确调用:

  1. 创建公共Mock函数文件mockMUI.jsx:
import vi from 'vitest';

export default function getMuiMocks() {
  return {
    Button: vi.fn().mockImplementation((props) => (
      <button className="mockedButton" {...props} />
    )),
    // 按需添加其他组件Mock
  };
}
  1. 在测试文件中使用:
import getMuiMocks from './mockMUI';

// 顶层调用Mock,传入公共工厂函数
vi.mock('@mui/material', () => getMuiMocks());

import { render, screen } from '@testing-library/react';
import App from './App';

describe("App tests", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it('渲染Mock按钮', () => {
    render(<App />);
    // 测试逻辑
  });
});

关键注意事项

  • 永远不要在beforeEach、it等测试钩子中调用vi.mock,必须放在文件顶层作用域
  • 避免直接导出Mock对象供vi.mock使用,改用函数返回的方式,确保变量初始化顺序正确
  • 若只需Mock部分组件,不要使用vi.importActual全量导入原模块,只导出需要Mock的组件即可提升测试速度

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 18:55:10