Testowanie logiki biznesowej - composables i Pinia stores.
1// composables/useCounter.js
2import { ref, computed } from 'vue'
3
4export function useCounter(initialValue = 0) {
5 const count = ref(initialValue)
6 const doubled = computed(() => count.value * 2)
7
8 function increment() {
9 count.value++
10 }
11
12 function decrement() {
13 count.value--
14 }
15
16 return { count, doubled, increment, decrement }
17}
18
19// composables/useCounter.spec.js
20import { describe, it, expect } from 'vitest'
21import { useCounter } from './useCounter'
22
23describe('useCounter', () => {
24 it('initializes with default value', () => {
25 const { count } = useCounter()
26 expect(count.value).toBe(0)
27 })
28
29 it('initializes with custom value', () => {
30 const { count } = useCounter(10)
31 expect(count.value).toBe(10)
32 })
33
34 it('increments count', () => {
35 const { count, increment } = useCounter()
36
37 increment()
38
39 expect(count.value).toBe(1)
40 })
41
42 it('computes doubled value', () => {
43 const { count, doubled, increment } = useCounter()
44
45 expect(doubled.value).toBe(0)
46
47 increment()
48
49 expect(doubled.value).toBe(2)
50 })
51})1// composables/useFetch.js
2import { ref } from 'vue'
3
4export function useFetch(url) {
5 const data = ref(null)
6 const loading = ref(false)
7 const error = ref(null)
8
9 async function fetchData() {
10 loading.value = true
11 error.value = null
12
13 try {
14 const response = await fetch(url)
15 data.value = await response.json()
16 } catch (e) {
17 error.value = e
18 } finally {
19 loading.value = false
20 }
21 }
22
23 return { data, loading, error, fetchData }
24}
25
26// composables/useFetch.spec.js
27import { describe, it, expect, vi, beforeEach } from 'vitest'
28import { useFetch } from './useFetch'
29
30describe('useFetch', () => {
31 beforeEach(() => {
32 global.fetch = vi.fn()
33 })
34
35 it('fetches data successfully', async () => {
36 const mockData = { id: 1, title: 'Test' }
37
38 global.fetch.mockResolvedValue({
39 json: async () => mockData
40 })
41
42 const { data, loading, error, fetchData } = useFetch('/api/test')
43
44 expect(loading.value).toBe(false)
45 expect(data.value).toBe(null)
46
47 await fetchData()
48
49 expect(loading.value).toBe(false)
50 expect(data.value).toEqual(mockData)
51 expect(error.value).toBe(null)
52 })
53
54 it('handles errors', async () => {
55 global.fetch.mockRejectedValue(new Error('Network error'))
56
57 const { data, error, fetchData } = useFetch('/api/test')
58
59 await fetchData()
60
61 expect(data.value).toBe(null)
62 expect(error.value).toBeInstanceOf(Error)
63 })
64})1// stores/gallery.spec.js
2import { describe, it, expect, beforeEach, vi } from 'vitest'
3import { setActivePinia, createPinia } from 'pinia'
4import { useGalleryStore } from './gallery'
5
6describe('Gallery Store', () => {
7 beforeEach(() => {
8 setActivePinia(createPinia())
9 })
10
11 it('initializes with empty artworks', () => {
12 const store = useGalleryStore()
13 expect(store.artworks).toEqual([])
14 })
15
16 it('fetches artworks', async () => {
17 const mockArtworks = [
18 { id: 1, title: 'Mona Lisa' },
19 { id: 2, title: 'Last Supper' }
20 ]
21
22 global.fetch = vi.fn().mockResolvedValue({
23 ok: true,
24 json: async () => mockArtworks
25 })
26
27 const store = useGalleryStore()
28
29 await store.fetchArtworks()
30
31 expect(store.artworks).toEqual(mockArtworks)
32 expect(store.isLoading).toBe(false)
33 })
34
35 it('handles fetch errors', async () => {
36 global.fetch = vi.fn().mockResolvedValue({
37 ok: false
38 })
39
40 const store = useGalleryStore()
41
42 await expect(store.fetchArtworks()).rejects.toThrow()
43 expect(store.error).toBeTruthy()
44 })
45
46 it('filters artworks by search', () => {
47 const store = useGalleryStore()
48
49 store.artworks = [
50 { id: 1, title: 'Mona Lisa', artist: 'Leonardo' },
51 { id: 2, title: 'Last Supper', artist: 'Leonardo' },
52 { id: 3, title: 'David', artist: 'Michelangelo' }
53 ]
54
55 store.filters.search = 'mona'
56
57 expect(store.filteredArtworks).toHaveLength(1)
58 expect(store.filteredArtworks[0].title).toBe('Mona Lisa')
59 })
60
61 it('adds artwork', async () => {
62 const newArtwork = { title: 'New Artwork', artist: 'Test' }
63 const savedArtwork = { id: 1, ...newArtwork }
64
65 global.fetch = vi.fn().mockResolvedValue({
66 ok: true,
67 json: async () => savedArtwork
68 })
69
70 const store = useGalleryStore()
71
72 const result = await store.addArtwork(newArtwork)
73
74 expect(store.artworks).toContainEqual(savedArtwork)
75 expect(result).toEqual(savedArtwork)
76 })
77})1// stores/gallery.js uses useAuthStore
2import { vi } from 'vitest'
3
4vi.mock('./auth', () => ({
5 useAuthStore: () => ({
6 token: 'fake-token',
7 isAuthenticated: true
8 })
9}))