Search code examples
vuejs3nuxt3.jsvitestvue-i18n

Mock @nuxtjs/i18n useLocalePath composable in unit test


I am trying to write test for Nuxt 3 component but I don't know how to mock useLocalePath() composable. Whatever I try I get TypeError: $setup.localePath is not a function

AppHeader.vue

<script setup lang="ts">
const { locale } = useI18n();
//const localePath = (path) => path;
const localePath = useLocalePath();
</script>

<template>
  <header class="shadow-sm bg-white">
    <div class="container mx-auto p-4 flex">
      <NuxtLink :to="localePath('/')" class="font-bold">{{
        $t('nuxt_playground')
      }}</NuxtLink>
      <select v-model="locale" class="ml-12">
        <option value="en">en</option>
        <option value="ee">ee</option>
      </select>
    </div>
  </header>
</template>

What I have tried

AppHeader.test.js

import { describe, it, expect, vi } from 'vitest';
import { mount } from '@vue/test-utils';
import AppHeader from './AppHeader.vue';

vi.mock('vue-i18n', () => {
  return {
    useI18n: () => {
      return {
        locale: 'en'
      };
    }
  };
});

vi.mock('@nuxtjs/i18n', () => {
  return {
    useLocalePath: (path) => path
  };
});

vi.mock('vue-i18n-routing', () => {
  return {
    useLocalePath: () => (path) => path
  };
});

describe('AppHeader', () => {
  it('should mount AppHeader', () => {
    const wrapper = mount(AppHeader, {
      shallow: true,
      global: {
        stubs: {
          NuxtLink: {
            template: "<div data-test='link'><slot></slot></div>"
          }
        },
        mocks: {
          $t: (msg) => msg
        }
      }
    });

    expect(wrapper.findAll('div[data-test="link"]')[0].attributes('to')).toBe(
      '/'
    );
  });
});

Thank you for any help. GitHub: https://github.com/SiimKirjanen/nuxt-playground

npm ci
npm run test:unit

Solution

  • I was able to mock it with mockNuxtImport

    import { mockNuxtImport } from '@nuxt/test-utils/runtime';
    
    mockNuxtImport('useLocalePath', () => {
      return () => (path) => path;
    });