Search code examples
vuejs3nuxt3.jsvitest

Auto-import vue reactivity system in vitest for testing composables in Nuxt 3 and vitest


I am using some utils in Nuxt 3. The vue reactivity system (ref, computed, ...) is also imported directly. However, it is not the case for the tests.

Running the spec file importing a ./useBusinessValidation composable throws the error ReferenceError: ref is not defined

Source file ./useBusinessValidation:

import { MaybeRef } from "@vueuse/core"

export const useBusinessValidation = <T>(rule: (payload: T) => true | string, payload: MaybeRef<T>) => {
  const validation = computed(() => rule(unref(payload)))

  const isValid = computed(() => validation.value === true)
  const errorMessage = computed(() => isValid.value ? undefined : validation.value as string)

  return {
    isValid,
    errorMessage
  }
}

Spec file useBusinessValidation.spec.ts:

import { useBusinessValidation } from "./useBusinessValidation"

describe('useBusinessValidation', async () => {
  it('should be valid with payload respecting the rule', () => {
    const rule = (x: number) => x > 0 ? true : `invalid ${x} number. Expected ${x} to be greater than 0.`
    const { isValid, errorMessage } = useBusinessValidation(rule, 0)

    expect(isValid.value).toBe(true)
    expect(errorMessage.value).toBe(undefined)
  });
})

and the vitest.config.ts

{
  resolve: {
    alias: {
      '~': '.',
      '~~': './',
      '@@': '.',
      '@@/': './',
      'assets': './assets',
      'public': './public',
      'public/': './public/'
    }
  },
  test: {
    globals: true,
    setupFiles: './test/setupUnit.ts',
    environment: 'jsdom',
    deps: { inline: [/@nuxt\/test-utils-edge/] },
    exclude: [
      'test/**/**.spec.ts',
      '**/node_modules/**',
      '**/dist/**',
      '**/cypress/**',
      '**/.{idea,git,cache,output,temp}/**'
    ]
  }
}

I also tried with the @vitejs/plugin-vue as

plugins: [Vue()]

in the vitest config. It didn't work out.


Solution

  • To auto-import in vitest, install the unplugin-auto-import.

    Then, in the vitest.config.ts add:

    import AutoImport from 'unplugin-auto-import/vite';
    
    export default defineConfig({
    ...
      plugins: [
        AutoImport({
          imports: [
            'vue',
            // could add 'vue-router' or 'vitest', whatever else you need.
          ],
       }),
      ]
    });