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

Vue3项目中VitestMock laravel-echo报错,求正确Mock方式

解决Vitest中Mock Laravel Echo的问题

一、针对模块导入的Laravel Echo

如果你的组件是通过import Echo from 'laravel-echo'引入使用的,正确的Mock方式是在测试文件顶部使用vi.mock的工厂函数,直接在工厂内部定义Mock对象(避免变量提升导致的错误):

// 测试文件顶部
import { vi } from 'vitest';
import Echo from 'laravel-echo';

vi.mock('laravel-echo', () => ({
  default: {
    // 模拟private方法,返回自身以支持链式调用
    private: vi.fn().mockReturnThis(),
    // 模拟listenToAll方法
    listenToAll: vi.fn(),
    // 如果用到notification,同样模拟
    notification: vi.fn().mockReturnThis()
  }
}));

Mock完成后,组件调用Echo.private().listenToAll()不会报错,还能在测试用例中做断言验证:

import { mount } from '@vue/test-utils';
import YourComponent from '@/components/YourComponent.vue';

test('组件挂载时正确订阅私有频道', () => {
  const mockUserId = 123;
  mount(YourComponent, {
    global: {
      provide: {
        user: { id: mockUserId }
      }
    }
  });

  // 断言private方法被传入正确参数调用
  expect(Echo.private).toHaveBeenCalledWith(`user.${mockUserId}`);
  // 断言listenToAll方法被调用
  expect(Echo.private().listenToAll).toHaveBeenCalled();
});

二、针对全局挂载的Laravel Echo

如果项目是把Echo挂载到window对象上(比如在resources/js/bootstrap.js中全局初始化),则需要在测试前后模拟/清理window.Echo:

import { vi } from 'vitest';
import { mount } from '@vue/test-utils';
import YourComponent from '@/components/YourComponent.vue';

beforeEach(() => {
  // 每个测试前初始化Mock的Echo
  window.Echo = {
    private: vi.fn().mockReturnThis(),
    listenToAll: vi.fn(),
    notification: vi.fn().mockReturnThis()
  };
});

afterEach(() => {
  // 测试后清理,避免污染其他用例
  delete window.Echo;
  vi.clearAllMocks();
});

test('组件监听私有频道事件', () => {
  mount(YourComponent);
  
  expect(window.Echo.private).toHaveBeenCalled();
  expect(window.Echo.private().listenToAll).toHaveBeenCalled();
});

错误原因分析

  1. TypeError: default.private is not a function:直接调用vi.mock('laravel-echo')时,Vitest会生成空Mock模块,默认导出没有private等方法,组件调用自然报错。必须显式定义Mock对象的结构。
  2. Error: [vitest] There was an error when mocking a module...:vi.mock的工厂函数会被Vitest提升到文件最顶部执行,此时外部定义的mockEcho变量还未初始化,导致报错。因此必须在工厂函数内部直接定义Mock对象,不能引用外部变量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 07:35:27