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

Vitest中BeforeEach未执行问题(Node.js单元测试)

Vitest参数化测试中beforeEach未执行、Mock调用次数无法重置问题排查

一、beforeEach未执行的核心原因

1. 测试结构的作用域问题

Vitest的钩子函数(beforeEach/beforeAll)必须放在describe块内部才能和测试用例绑定生效。如果直接在测试文件顶层写beforeEach,而参数化测试是独立的test.each块,钩子不会被触发。

错误写法示例:

beforeEach(() => {
  console.log('beforeEach');
  vi.clearAllMocks();
});

test.each(testCases)('参数化测试用例', (...args) => {
  // 测试逻辑
});

正确写法:把钩子和测试用例统一包裹到describe块中

describe('被测模块测试套件', () => {
  beforeEach(() => {
    console.log('beforeEach');
    vi.clearAllMocks();
  });

  test.each(testCases)('参数化测试用例', (...args) => {
    // 测试逻辑
  });
});

2. 钩子放置位置错误

如果之前注释过钩子函数又重新添加,可能不小心把beforeEach放到了错误作用域(比如test.each内部、嵌套过深的代码块里),检查代码结构,确保钩子是describe的直接子级。

二、Mock调用次数重置的正确操作

解决beforeEach执行问题后,还要确保mock重置逻辑到位:

  • 仅用vi.clearAllMocks()只能清除调用记录,如果你需要重置mock实现到初始状态,改用vi.resetAllMocks();
  • 若每次测试需要固定的mock实现,可在beforeEach里重新设置:
beforeEach(() => {
  // 清除所有mock的调用记录
  vi.clearAllMocks();
  // 重置mock实现到初始状态(可选,根据需求)
  // vi.resetAllMocks();
  // 重新设置特定mock的返回值/实现
  function1Mock.mockResolvedValue('默认测试返回值');
});

三、beforeAll/afterAll异常行为的修复

之前afterAll在每个参数化用例后执行,同样是作用域问题:
把beforeAll和afterAll放在最外层的describe块中,确保它们只在整个测试套件启动和结束时各执行一次:

describe('被测模块测试套件', () => {
  beforeAll(() => {
    // 初始化模块级mock,仅执行一次
    vi.mock('../utils', () => ({
      function1: vi.fn(),
    }));
  });

  afterAll(() => {
    // 恢复所有mock,仅在所有测试结束后执行
    vi.restoreAllMocks();
  });

  beforeEach(() => {
    vi.clearAllMocks();
  });

  test.each(testCases)('参数化测试用例', (...args) => {
    // 测试逻辑
  });
});

额外验证步骤

  1. 在beforeEach中添加明确的console.log,运行测试时查看控制台输出,确认钩子是否执行;
  2. 检查vitest.config.ts配置,确保没有禁用钩子的配置(比如test.hooks: false);
  3. 验证vi.mock()的模块路径是否正确,避免因模块解析错误导致mock失效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 20:21:02