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

如何在Vitest中Mock $csrfFetch?(基于nuxt-csurf模块)

如何在Vitest中Mock Nuxt的useCsrfFetch和$csrfFetch方法

我在项目中使用nuxt-csurf模块,因此必须通过useCsrfFetch和$csrfFetch方法发起请求。手动测试时功能正常,但在Vitest中需要对这两个函数进行Mock,尝试了两种方案都失败了:

方案一直接MockuseNuxtApp引发大量Nuxt内部错误:

vi.mock('../../node_modules/nuxt/dist/app/nuxt', async (importOriginal) => {
    const actual = await importOriginal();
    return {
        ...actual,
        useNuxtApp: vi.fn(() => {
            const nuxtApp = actual.useNuxtApp();
            return {
                ...nuxtApp,
                $csrfFetch: vi.fn(async (...args) => {
                    console.log('$csrfFetch called with:', args);
                    return { data: 'mocked response' };
                }),
            };
        }),
    };
});

方案二尝试SpyOn$csrfFetch时抛出错误:

const nuxtApp = useNuxtApp();
const spy = vi.spyOn(nuxtApp, '$csrfFetch').mockImplementation(() =>
    Promise.resolve({ state: 'response data' }),
);

TypeError: Cannot redefine property: $csrfFetch


正确的Mock方案

1. 直接Mock useCsrfFetch

如果代码中直接调用useCsrfFetch,可以直接Mock这个函数:

// 在测试文件顶部执行
vi.mock('#app', () => ({
  useCsrfFetch: vi.fn(async (...args) => {
    console.log('useCsrfFetch called with:', args);
    return Promise.resolve({ data: 'mocked response' });
  })
}));

2. Mock NuxtApp中的$csrfFetch

如果代码通过useNuxtApp()获取$csrfFetch,直接MockuseNuxtApp返回包含模拟方法的对象即可,无需调用原函数:

vi.mock('#app', () => ({
  useNuxtApp: vi.fn(() => ({
    $csrfFetch: vi.fn(async (...args) => {
      console.log('$csrfFetch called with:', args);
      return Promise.resolve({ state: 'response data' });
    })
  }))
}));

3. 组件测试中通过Provide注入Mock

测试Vue组件时,也可以通过provide直接注入Mock的$csrfFetch:

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

test('组件调用$csrfFetch时触发Mock', async () => {
  const mockCsrfFetch = vi.fn(() => Promise.resolve({ data: 'test data' }));
  
  const wrapper = mount(YourComponent, {
    global: {
      provide: {
        $csrfFetch: mockCsrfFetch
      }
    }
  });

  // 触发组件中调用$csrfFetch的操作
  await wrapper.find('.submit-btn').trigger('click');

  expect(mockCsrfFetch).toHaveBeenCalled();
});

原方案失败原因说明

  • 方案一:直接Mocknuxt/dist/app/nuxt中的useNuxtApp并调用原函数,会破坏Nuxt内部的上下文依赖链,测试环境无法提供原函数所需的运行上下文,因此引发大量内部错误。
  • 方案二:$csrfFetch是Nuxt注入的不可配置属性,vi.spyOn无法修改这类属性,因此抛出Cannot redefine property错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 04:25:00