floriankapaun
floriankapaun

Reputation: 827

Nuxt Vitest Mock useRoute in another module

I am trying to write a test for the following Nuxt 3 composable (useLinkToSlug).

import { computed } from 'vue';

export default function () {
    const route = useRoute();
    return computed(() => route?.params?.slug ? `/${route.params.slug}` : undefined);
}

To keep the code as lean as possible, I tried to mock the vue-router module and set the return of useRoute() manually.

My test looks like this:

import { vi, it, expect, describe } from 'vitest';

import useLinkToSlug from '~~/composables/useLinkToSlug';

describe('useLinkToSlug', () => {
    it('should return link to slug', () => {
        vi.mock('vue-router', () => ({
            useRoute: () => ({ params: { slug: 'abc' } })
        }));

        const link = useLinkToSlug();

        expect(link.value).toEqual('/abc');
    });

    it('should return null', () => {
        vi.mock('vue-router', () => ({
            useRoute: () => ({ params: { slug: undefined } })
        }));

        const link = useLinkToSlug();

        expect(link.value).toBeNull();
    });
});

The first one succeeds, but the later one fails, with:

AssertionError: expected '/abc' to be null

I don't get why and what to do, to make this work.

Using: Nuxt3 with Vitest

Upvotes: 3

Views: 5500

Answers (1)

floriankapaun
floriankapaun

Reputation: 827

Got it now. Was so close. Solution:

Add import statement for useRoute to composable.

import { computed } from 'vue';
import { useRoute } from 'vue-router'; // added this import statement

export default function () {
    const route = useRoute();
    return computed(() => route?.params?.slug ? `/${route.params.slug}` : undefined);
}

Mock vue-router:

import { vi, it, expect, describe } from 'vitest';

import useLinkToSlug from '~~/composables/useLinkToSlug';

vi.mock('vue-router'); // mock the import

describe('useLinkToSlug', () => {
    it('should return link to slug', () => {
        const VueRouter = await import('vue-router');

        VueRouter.useRoute.mockReturnValueOnce({
            params: { slug: 'abc' }
        });

        const link = useLinkToSlug();

        expect(link.value).toEqual('/abc');
    });

    it('should return null', () => {
        const VueRouter = await import('vue-router');

        VueRouter.useRoute.mockReturnValueOnce({
            params: { slug: undefined }
        });

        const link = useLinkToSlug();

        expect(link.value).toBeNull();
    });
});

Upvotes: 5

Related Questions