Search code examples
typescriptnuxt.jscsrfvitest

How can I mock $csrfFetch in Vitest?


In my app, I use the nuxt-csurf module.

Meaning, I have to use useCsrfFetch and $csrfFetch.

This works fine during manual testing, but in Vitest I need to mock these functions.

I have tried:

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' };
                }),
            };
        }),
    };
});

But that throw a lot of other internal nuxt errors.

And I have tried:

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

But that throws:

TypeError: Cannot redefine property: $csrfFetch

Any help is appreciated


Solution

  • Apparently, I can just do it like this:

    const { mockUseNuxtApp } = vi.hoisted(() => ({
        mockUseNuxtApp: vi.fn(() => ({
            $csrfFetch: vi.fn(),
        })),
    }));
    
    mockNuxtImport('useNuxtApp', () => mockUseNuxtApp);
    
    describe('...', () => {
        afterEach(() => {
            mockFetch.mockReset();
        });
        it('...', async () => {
          mockUseNuxtApp.mockReturnValue({
              $csrfFetch: vi.fn(),
          });
          
          // do somthing where $csrfFetch is used
          
        });
    });