Vitest报错:expected 'spy' to be called at least once求助
问题:断言
expect(log.warn).toHaveBeenCalled()失败,明明action里调用了log.warn 执行断言expect(log.warn).toHaveBeenCalled()时,报错“expected "spy" to be called at least once”,但被测Vue Store的handleServerError action中明确调用了log.warn(.....),无法理解原因。
单元测试代码
describe('handleServerError', () => { it('should set error message in store and log the error', () => { vi.mock('common/helpers/server-error-message.js', async () => { const actual = await vi.importActual('common/helpers/server-error-message.js'); return { ...actual, getErrorCodeFromEvent: () => 27001, }; }); actions.handleServerError(context); expect(context.commit).toHaveBeenCalledWith('setServerErrorCode', 27001); expect(log.warn).toHaveBeenCalled(); }); });
Vue Store action代码
handleServerError(context, e) { log.warn(getServerErrorLogMessage('getLicenses', e)); const code = getErrorCodeFromEvent(e); context.commit('setServerErrorCode', code); },
可能的解决方向
未正确创建
log.warn的spy:必须确保log.warn被设置为Vitest的spy对象,否则无法捕获调用。如果log是从模块导入的,先对其方法进行spy:import * as log from '@/utils/log'; // 替换为实际路径 // 在测试用例开头创建spy vi.spyOn(log, 'warn').mockImplementation(() => {});如果是全局
console的别名,也要spy对应的全局对象:vi.spyOn(console, 'warn').mockImplementation(() => {});action调用缺少必要参数
e:action定义需要第二个参数e,但测试中调用actions.handleServerError(context)时未传入。getServerErrorLogMessage接收e作为参数,若e为undefined可能抛出异常,导致log.warn未执行。补充模拟参数:// 传入模拟的e对象,根据函数需求构造必要属性 actions.handleServerError(context, { message: 'mock error' });mock覆盖不完整导致函数异常:
getServerErrorLogMessage可能依赖了未被正确mock的逻辑,导致执行失败中断代码。可以在mock模块时同时覆盖这个函数:vi.mock('common/helpers/server-error-message.js', async () => { const actual = await vi.importActual('common/helpers/server-error-message.js'); return { ...actual, getErrorCodeFromEvent: () => 27001, getServerErrorLogMessage: () => '模拟错误日志内容' // 新增mock该函数 }; });spy创建时机错误:确保spy是在action调用之前创建的,否则无法捕获到调用行为。调整代码顺序:
it('should set error message in store and log the error', () => { // 先创建spy vi.spyOn(log, 'warn').mockImplementation(() => {}); // 再调用action actions.handleServerError(context, {}); // 最后断言 expect(context.commit).toHaveBeenCalledWith('setServerErrorCode', 27001); expect(log.warn).toHaveBeenCalled(); });
内容的提问来源于stack exchange,提问作者matmik
相关产品推荐
相关产品推荐

