Тестирование хранилища Pinia внутри Nuxt3 с помощью vitest выдает `useRuntimeConfig` не определено

Я тестирую магазин пиния в nuxt3приложение.

Внутри setup()магазина, которым я пользуюсь useRuntimeConfigчтобы получить начальное значение счетчика из общедоступных переменных конфигурации, и я получил эту ошибку ReferenceError: useRuntimeConfig is not definedне знаю как решить

      // store/counter.ts

...
state: () => {
    const runtimeConfig = useRuntimeConfig()
    const count = runtimeConfig.public.count
    return {
      ...
      count
      ...
    }
  },
...

код

      // store/counter.test.ts

import { fileURLToPath } from 'node:url'
import { describe, expect, it, beforeEach } from 'vitest'
import { setActivePinia, createPinia } from 'pinia'
import { useCounter } from './counter'
import { setup } from '@nuxt/test-utils'

await setup({
  rootDir: fileURLToPath(new URL('../', import.meta.url)),
  server: true,
  browser: true,
})

describe('Counter Store', () => {
  beforeEach(() => {
    // creates a fresh pinia and make it active so it's automatically picked
    // up by any useStore() call without having to pass it to it:
    // `useStore(pinia)`
    setActivePinia(createPinia())
  })

  it('increments', () => {
    const counter = useCounter()
    expect(counter.n).toBe(0)
    counter.increment()
    expect(counter.n).toBe(1)
  })

  it('increments by amount', () => {
    const counter = useCounter()
    counter.increment(10)
    expect(counter.n).toBe(10)
  })
})

3 ответа

Это похоже на проблему, которую я только что решил сегодня. Надеюсь, это поможет и вам:

  1. В вашем компоненте, в данном случае в модуле хранилища Pinia, добавьте явный импорт для useRuntimeConfig, как показано ниже:

    import { useRuntimeConfig } from '#imports'

На данный момент у меня нет лучшего способа обойти «неопределенный» пакет, кроме как просто импортировать его вручную. Я надеюсь, что по мере развития Nuxt3 тестирование будет уделяться больше внимания. Документация, кажется, предлагает импортировать его из «#app», но я не смог заставить его работать таким образом, и «#imports» показался более подходящим псевдонимом.

  1. В вашем vitest.config.js добавьте псевдоним, который сопоставляет пакет со скрытым файлом nuxt. Пример файла vitest.config.js приведен ниже:
      export default defineConfig({
  test: {
    // other test specific plugins
  },
  plugins: [vue()],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './'),
      '~': path.resolve(__dirname, './'),
      '#imports': path.resolve(__dirname, './.nuxt/imports.d.ts')
    }
  }
})
  1. В тестовом файле используйте функцию vi.mock(), чтобы имитировать #importsупаковка.
       vi.mock('#imports', () => {
    return {
      useRuntimeConfig() {
        return {
          public: {
            // Your public config!
          }
        }
      }
    }
  })

Это позволило мне смоделировать runtimeConfig на тестовом уровне — надеюсь, вам это тоже поможет! Удачи :D

Для тех, кто читает это и хочет добиться того же в Jest, это обсуждение GitHub помогло мне найти это решение.

У меня была такая же проблема, но я не хотел явно импортировать составные части в компоненты. Мне очень помог плагин unplugin-auto-import/vite, который мне очень помог .

С моим vitest.conf.ts я могу издеваться над моим useRoute, не импортируя его явно в компонент.

vitest.config.ts

      import { defineConfig } from 'vitest/config'
import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite'

export default defineConfig({
  root: '.',
  plugins: [
    vue(),
    AutoImport({
      /* options */
      imports: ['vue-router'],
    }),
  ],

  test: {
    globals: true,
    environment: 'jsdom',
    setupFiles: './setupTests.ts',
  },
  // ... standart nuxt resolve stuff from ./.nuxt/tsconfig.json
})

VueComponent.vue

      <script setup lang="ts">
const route = useRoute()
defineProps<{
  componentName?: string
}>()
</script>

<template>
  <div>
    {{ route.fullPath }}
  </div>
</template>

твои тесты

      import VueComponent from '@/components/VueComponent.vue'
import { render, screen } from '@testing-library/vue'
import '@testing-library/jest-dom'
import { vi } from 'vitest'

describe('Default Content Component', () => {
  test('Renders Content', () => {
    render(VueComponent, {
      global: {
        mocks: {
          route: { fullPath: 'asds' },
        },
      },
    })
    // ... your assertions
  })
})

я использовал витестнасколько эффективно думали тестыбыло неопределенным, я мог бы установить его в своем тесте следующим образом:

      globalThis.useRuntimeConfig = () => {
  return {
    public: {
       something: 'value'
    },
  };
};

Делюсь своими мыслями с @KatieAdamsDev и надеюсь, что автоматический импорт с помощью nuxt-тестов станет немного проще. На данный момент вышеизложенное не кажется правильным долгосрочным решением, но я подожду, пока команда Nuxt определит, что это такое.

Другие вопросы по тегам