Store Testing
13.4.1. createTestingPinia
In test environments, createTestingPinia() from @pinia/testing must be used to create a testing Pinia instance.
createTestingPinia()automatically mocks all actions.- Setting
stubActions: falsecauses actual actions to be executed. initialStatemay be used to override a Store's initial state.
typescript
import { createTestingPinia } from '@pinia/testing'
import { vi } from 'vitest'
// Default usage: all actions are automatically mocked.
const pinia = createTestingPinia({
createSpy: vi.fn,
})
// When actions should actually execute
const pinia = createTestingPinia({
createSpy: vi.fn,
stubActions: false,
})
// When specifying initial state
const pinia = createTestingPinia({
createSpy: vi.fn,
initialState: {
user: { user: { id: 1, name: 'Test User' }, loading: false },
cart: { items: [{ id: 1, name: 'Product A', price: 10000, quantity: 2 }] },
},
})13.4.2. Store Unit Testing
When testing a Store independently without a component, setActivePinia() must be used.
typescript
// src/stores/__tests__/useCartStore.test.ts
import { describe, it, expect, beforeEach } from 'vitest'
import { setActivePinia, createPinia } from 'pinia'
import { useCartStore } from '../useCartStore'
describe('useCartStore', () => {
beforeEach(() => {
setActivePinia(createPinia())
})
it('should have an empty array as the initial state', () => {
const store = useCartStore()
expect(store.items).toEqual([])
expect(store.isEmpty).toBe(true)
})
it('should correctly calculate totalPrice when items are added', () => {
const store = useCartStore()
store.items.push({ id: 1, name: 'Product A', price: 5000, quantity: 3 })
expect(store.totalPrice).toBe(15000)
expect(store.itemCount).toBe(1)
})
it('should restore to initial state when resetState is called', () => {
const store = useCartStore()
store.items.push({ id: 1, name: 'Product A', price: 5000, quantity: 1 })
store.resetState()
expect(store.items).toEqual([])
})
})- A new Pinia instance must be created in
beforeEachto prevent state contamination between tests. - Getters must be verified by asserting the return value after a state change.
13.4.3. Store Testing within Components
When a component uses a Store, createTestingPinia() must be injected via mount's global.plugins.
typescript
// src/components/__tests__/UserProfile.test.ts
import { describe, it, expect } from 'vitest'
import { mount } from '@vue/test-utils'
import { vi } from 'vitest'
import { createTestingPinia } from '@pinia/testing'
import UserProfile from '../UserProfile.vue'
import { useUserStore } from '@/stores/useUserStore'
describe('UserProfile', () => {
it('should display the user name', () => {
const wrapper = mount(UserProfile, {
global: {
plugins: [
createTestingPinia({
createSpy: vi.fn,
initialState: {
user: {
user: { id: 1, name: 'John Doe' },
loading: false,
},
},
}),
],
},
})
expect(wrapper.text()).toContain('John Doe')
})
it('should call loadCurrentUser on mount', () => {
const wrapper = mount(UserProfile, {
global: {
plugins: [createTestingPinia({ createSpy: vi.fn })],
},
})
const userStore = useUserStore()
expect(userStore.loadCurrentUser).toHaveBeenCalledOnce()
})
})- The keys in
initialStatemust match the Store ID passed todefineStore. - Calling
useUserStore()after mounting the component returns the testing Store instance.
13.4.4. Mocking Patterns
API Call Mocking
API calls within a Store must be mocked using vi.mock().
typescript
import { describe, it, expect, beforeEach, vi } from 'vitest'
import { setActivePinia, createPinia } from 'pinia'
import { useUserStore } from '../useUserStore'
import { fetchCurrentUser } from '@/api/user'
vi.mock('@/api/user', () => ({
fetchCurrentUser: vi.fn(),
}))
describe('useUserStore - API integration', () => {
beforeEach(() => {
setActivePinia(createPinia())
vi.clearAllMocks()
})
it('should store user info on successful loadCurrentUser', async () => {
const mockUser = { id: 1, name: 'Test User' }
vi.mocked(fetchCurrentUser).mockResolvedValue(mockUser)
const store = useUserStore()
await store.loadCurrentUser()
expect(store.user).toEqual(mockUser)
expect(store.isLoggedIn).toBe(true)
expect(store.loading).toBe(false)
})
})Action Mocking
When createTestingPinia() is used, all actions are automatically mocked. To specify the return value of a specific action, use mockResolvedValue().
typescript
const pinia = createTestingPinia({ createSpy: vi.fn })
const userStore = useUserStore()
vi.mocked(userStore.loadCurrentUser).mockResolvedValue(undefined)- With
stubActions: true(default), only action invocation should be verified. - To test the actual action logic, specify
stubActions: falseor write a separate Store unit test.