Тестувати сам стор просто: створити свіжий екземпляр Pinia і викликати дії.
import { setActivePinia, createPinia } from 'pinia';
beforeEach(() => setActivePinia(createPinia()));
test('додає товар у кошик', () => {
const cart = useCartStore();
cart.add({ id: 1, price: 100 });
expect(cart.total).toBe(100);
});
Тестувати компонент зі стором складніше: справжні дії ходять в API, а стан треба підготувати. Для цього пакет @pinia/testing:
import { mount } from '@vue/test-utils';
import { createTestingPinia } from '@pinia/testing';
import { vi } from 'vitest';
test('кнопка оформлення викликає checkout', async () => {
const wrapper = mount(CartSummary, {
global: {
plugins: [
createTestingPinia({
createSpy: vi.fn,
initialState: {
cart: { items: [{ id: 1, price: 100, qty: 2 }] },
},
}),
],
},
});
const cart = useCartStore();
await wrapper.get('button').trigger('click');
expect(cart.checkout).toHaveBeenCalledTimes(1);
expect(wrapper.text()).toContain('200');
});
Як це працює:
- дії замінені шпигунами (
stubActionsза замовчуванням увімкнено):checkoutне виконується, але можна перевірити, що її викликали й з якими аргументами.stubActions: false- дії виконуються по-справжньому, але все одно відстежуються; initialState- стан за назвою стору (id зdefineStore), без дій для його підготовки;createSpy: vi.fn- потрібен, якщо у Vitest не ввімкненоglobals: true;- гетери можна перевизначити в тесті присвоєнням (
cart.total = 999), аundefinedповертає звичайне обчислення.
Що варто пам'ятати:
useCartStore()у тесті треба викликати після монтування з тестовою Pinia - тоді повертається той самий екземпляр, що бачить компонент;- стан змінюється напряму (
cart.items = []) - і компонент реагує, бо реактивність справжня; - окремі тести для дій сторів з реальною логікою й замоканим HTTP-клієнтом - компонентні тести зі шпигунами не перевіряють, що дія робить правильні речі.
TypeScript: шпигуни мають тип звичайних функцій; для доступу до mock.calls - vi.mocked(cart.checkout).