使用 vitest 测试 Nuxt3 内的 Pinia 存储会抛出“useRuntimeConfig”未定义

Its*_*thn 4 nuxt.js vite nuxtjs3 pinia vitest

我正在nuxt3应用程序中测试 pinia 商店。

在商店内部setup(),我用来useRuntimeConfig从公共配置变量中获取计数器的初始值,但出现此错误,ReferenceError: useRuntimeConfig is not defined不知道如何解决

// store/counter.ts

...
state: () => {
    const runtimeConfig = useRuntimeConfig()
    const count = runtimeConfig.public.count
    return {
      ...
      count
      ...
    }
  },
...
Run Code Online (Sandbox Code Playgroud)

代码

// 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)
  })
})

Run Code Online (Sandbox Code Playgroud)

Kat*_*Dev 9

这看起来与我今天刚刚解决的问题相似。希望它也对您有帮助:

  1. 在您的组件中,在本例中为 Pinia 存储模块,添加 useRuntimeConfig 的显式导入,如下所示:

    import { useRuntimeConfig } from '#imports'

目前,除了手动导入包之外,我没有更好的方法来解决包“未定义”的问题。随着 Nuxt3 的进展,我希望看到测试变得更加受关注。文档似乎建议从“#app”导入它,但我无法让它以这种方式工作,“#imports”似乎是更合适的别名。

  1. 在 vitest.config.js 中,添加一个别名,将#imports包映射到隐藏的 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')
    }
  }
})
Run Code Online (Sandbox Code Playgroud)
  1. 在您的测试文件中,使用 vi.mock() 函数来模拟#imports包。
 vi.mock('#imports', () => {
    return {
      useRuntimeConfig() {
        return {
          public: {
            // Your public config!
          }
        }
      }
    }
  })
Run Code Online (Sandbox Code Playgroud)

这使我能够在测试级别模拟 runtimeConfig - 希望它也对您有帮助!祝你好运:D

对于任何阅读本文并希望在 Jest 中实现类似目标的人来说,这是 GitHub 讨论,它帮助我找到了这个解决方案。不幸的是,我用于创建此解决方案的讨论已不再存在。(404)

编辑:如果您需要在逐个测试的基础上更改模拟返回值,您可以返回在其他地方定义的对象并更改测试中该对象的值。

IE

    let storeMock = {
       user: {
         getUsername: 'Jane Doe',
         setUsername: vi.fn()
       }
    }

    vi.mock('#imports', () => {
        return {
           useNuxtApp: vi.fn().mockImplementation(() => ({
               $store: {
                   ...storeMock
               }
           })),
        }
    })

    // In your test
    storeMock = {
        user: {
            getUsername: 'Janet Van Dyne',
            setUsername: vi.fn()
        }
    }
Run Code Online (Sandbox Code Playgroud)