组件内函数修改Pinia Store状态的测试未生效,如何排查?
问题分析与解决
你的测试失败核心原因是获取store实例的时机错误:在挂载组件前调用useUiStore(),此时Testing Pinia还未注入到Vue测试环境中,你拿到的是原始的store实例,和组件内部使用的测试用store不是同一个,所以组件修改状态后,你断言的实例不会同步更新。
修正方案1:调整store获取时机
将useUiStore()的调用移到组件挂载之后,确保获取的是测试环境中的store实例:
it('sets the uiStore.isNotificationsOpen when openNotificationsDialog is called', async () => { const wrapper = mount(NavigationBar, { plugins: [createTestingPinia({ createSpy: vi.fn })], }) as VueWrapper<typeof NavigationBar>; // 挂载组件后再获取store const uiStore = useUiStore(); expect(uiStore.isNotificationsOpen).toBe(false); await wrapper.vm.openNotificationsDialog(); await wrapper.vm.$nextTick(); expect(uiStore.isNotificationsOpen).toBe(true); });
修正方案2:检查action是否被mock(如果使用action修改状态)
如果你的openNotificationsDialog是通过调用store的action来修改状态(而非直接修改state),需要注意createTestingPinia默认会mock所有action,导致实际的状态修改逻辑不会执行。此时需要添加stubActions: false配置:
假设你的store定义如下:
export const useUiStore = defineStore('ui', { state: () => ({ isNotificationsOpen: false }), actions: { toggleNotifications() { this.isNotificationsOpen = true; } } });
测试代码需要调整:
it('sets the uiStore.isNotificationsOpen when openNotificationsDialog is called', async () => { const wrapper = mount(NavigationBar, { plugins: [createTestingPinia({ createSpy: vi.fn, stubActions: false // 关闭action mock,执行实际逻辑 })], }) as VueWrapper<typeof NavigationBar>; const uiStore = useUiStore(); expect(uiStore.isNotificationsOpen).toBe(false); await wrapper.vm.openNotificationsDialog(); await wrapper.vm.$nextTick(); expect(uiStore.isNotificationsOpen).toBe(true); });
额外检查点
- 确认
openNotificationsDialog方法内部逻辑正确,确实在修改isNotificationsOpen状态(比如直接赋值或调用正确的action) - 若使用Vue 3 + Script Setup,确保组件正确引入并使用了
useUiStore()
内容的提问来源于stack exchange,提问作者TheYuwana
相关产品推荐
相关产品推荐

