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) => { // 测试逻辑 }); });
额外验证步骤
- 在
beforeEach中添加明确的console.log,运行测试时查看控制台输出,确认钩子是否执行; - 检查
vitest.config.ts配置,确保没有禁用钩子的配置(比如test.hooks: false); - 验证
vi.mock()的模块路径是否正确,避免因模块解析错误导致mock失效。
内容的提问来源于stack exchange,提问作者Maya
相关产品推荐
相关产品推荐

