You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3从Vuex转Pinia后单元测试失败,无法创建自定义模拟Store

解决Pinia在Vue3单元测试中自定义模拟Store的问题

下面提供两种可行方案,帮你在Jest+vue/test-utils环境中创建可被组件使用的自定义测试Pinia Store:

方案1:创建测试专用Pinia实例并注入自定义Store

这种方法适合直接在测试文件中定义临时测试Store,无需修改原代码:

  1. 初始化Pinia测试实例并设置为活跃状态
  2. 定义自定义测试Store
  3. 挂载组件时将Pinia实例作为插件传入
import { createPinia, setActivePinia, defineStore } from 'pinia'
import { mount } from '@vue/test-utils'
import PasswordResetPage from '@/views/PasswordReset.vue'

let pinia
let authTestStore

beforeEach(() => {
  // 创建Pinia实例并激活,避免"找不到活跃Pinia实例"错误
  pinia = createPinia()
  setActivePinia(pinia)

  // 定义自定义测试Store,模拟密码重置成功逻辑
  const useCustomAuthStore = defineStore('AuthenticationStore', {
    state: () => ({
      passwordResetSuccess: false
    }),
    actions: {
      forgotPasswordResetPassword() {
        // 绕过后端,直接更新状态
        this.passwordResetSuccess = true
      }
    }
  })

  // 实例化测试Store
  authTestStore = useCustomAuthStore()
})

test('点击重置按钮后状态更新为成功', async () => {
  const wrapper = mount(PasswordResetPage, {
    global: {
      plugins: [pinia]
    }
  })

  // 触发重置按钮点击事件
  await wrapper.find('#reset-password-btn').trigger('click')

  // 验证状态是否正确更新
  expect(authTestStore.passwordResetSuccess).toBe(true)
})

方案2:Jest Mock原Store模块

如果你的项目中将useAuthenticationStore定义在单独的store文件中(比如src/stores/authentication.js),可以直接Mock整个模块:

import { createPinia, setActivePinia, defineStore } from 'pinia'
import { mount } from '@vue/test-utils'
import PasswordResetPage from '@/views/PasswordReset.vue'

// Mock原Store模块,替换为自定义测试Store
jest.mock('@/stores/authentication', () => {
  const useMockAuthStore = defineStore('AuthenticationStore', {
    state: () => ({
      passwordResetSuccess: false
    }),
    actions: {
      forgotPasswordResetPassword() {
        this.passwordResetSuccess = true
      }
    }
  })

  return { useAuthenticationStore: useMockAuthStore }
})

beforeEach(() => {
  // 激活Pinia实例,确保Mock的Store能正常初始化
  const pinia = createPinia()
  setActivePinia(pinia)
})

test('触发重置操作后状态标记为成功', async () => {
  const wrapper = mount(PasswordResetPage, {
    global: {
      plugins: [createPinia()]
    }
  })

  // 获取Mock的Store实例
  const { useAuthenticationStore } = require('@/stores/authentication')
  const authStore = useAuthenticationStore()

  // 触发按钮点击
  await wrapper.find('.reset-btn').trigger('click')

  // 验证状态更新
  expect(authStore.passwordResetSuccess).toBe(true)
})

关键注意事项

  • 必须在调用defineStore和useStore之前执行setActivePinia(pinia),否则会抛出"找不到活跃Pinia实例"的错误
  • 如果action是异步函数,测试时要添加await等待执行完成
  • 若组件中使用storeToRefs获取状态,测试时可直接通过Store实例访问状态,无需额外处理响应式问题

内容的提问来源于stack exchange,提问作者DaveCode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 00:30:44