Adri HM
Adri HM

Reputation: 3100

Test a component with Vitest using useNuxtApp with Nuxt 3

I want to test a component using the useNuxtApp composable. This is the component(MyComponent.vue):

<template>
  <div class="flex justify-between">
    <span>{{ $fmt(12) }}</span>
  </div>
</template>

<script lang="ts" setup>
const { $fmt } = useNuxtApp()
</script>

$fmt is a plugin in plugins folder.

The problem is when I try to test MyComponent.vue with vitest, the test is not started and this error appears:

ReferenceError: useNuxtApp is not defined

I don't know how to mock the useNuxtApp composable

Upvotes: 9

Views: 8588

Answers (2)

oerol
oerol

Reputation: 147

Instead of mocking, you can use stubbing:

vi.stubGlobal("useNuxtApp", () => ({
  $fmt: vi.fn(),
}));

If you need to mock functions of $fmt (let's say doSomething()), then just extend it like this:

vi.stubGlobal("useNuxtApp", () => ({
  $fmt: { doSomething: vi.fn() },
}));

Upvotes: 4

Adri HM
Adri HM

Reputation: 3100

The solution is to import useNuxtApp in your component:

<template>
  <div class="flex justify-between">
    <span>{{ $fmt(12) }}</span>
  </div>
</template>

<script lang="ts" setup>
import { useNuxtApp } from '#app'
const { $fmt } = useNuxtApp()
</script>

add the #app and #head aliases in vitest.config.js to import useNuxtApp in your test file also:

import path from 'path'
import vue from '@vitejs/plugin-vue'

export default {
  plugins: [vue()],
  test: {
    globals: true,
    environment: 'jsdom',
    setupFiles: './tests/unit/setup/index.ts',
  },
  resolve: {
    alias: {
      '@': path.resolve(__dirname, '.'),
      '#app': path.resolve(
        __dirname,
        './node_modules/nuxt/dist/app/index.d.ts'
      ),
      '#head': path.resolve(
        __dirname,
        './node_modules/nuxt/dist/app/index.d.ts'
      ),
    },
  },
}

And finally you can mock useNuxtApp in your test file:

import { vi } from 'vitest'
import * as nuxt from '#app'
import { currency } from '@/plugins/utils/fmt-util'

// @ts-ignore
vi.spyOn(nuxt, 'useNuxtApp').mockImplementation(() => ({
  $fmt: { currency },
}))

Upvotes: 3

Related Questions