Skip to content

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: false causes actual actions to be executed.
  • initialState may 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 beforeEach to 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 initialState must match the Store ID passed to defineStore.
  • 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: false or write a separate Store unit test.

TIENIPIA QUALIFIED STANDARD