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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 08:45:38