9

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

2 Answers 2

4

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 },
}))
Sign up to request clarification or add additional context in comments.

Comments

4

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

1 Comment

works like a charm!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.