javascript / expert
Snippet
Testing Vue Composables via Subclass Mocking and Dependency Injection
Combining OOP inheritance with Vue Composition API composables allows seamless dependency injection in unit tests. By passing mock subclasses into composables, developers can test reactive state resolution cleanly without global monkey-patching.
snippet.js
javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import { ref } from 'vue';import { describe, it, expect } from 'vitest';export class BaseApiClient {async fetchData(): Promise<string[]> {return ['real-prod-data'];}}export class MockApiClient extends BaseApiClient {override async fetchData(): Promise<string[]> {return ['mock-alpha', 'mock-beta'];}}export function useDataFetcher(client = new BaseApiClient()) {const data = ref<string[]>([]);const load = async () => { data.value = await client.fetchData(); };return { data, load };}describe('useDataFetcher composable', () => {it('populates reactive state using injected mock class', async () => {const { data, load } = useDataFetcher(new MockApiClient());await load();expect(data.value).toEqual(['mock-alpha', 'mock-beta']);});});
vue
Breakdown
1
export class MockApiClient extends BaseApiClient
Creates a test mock subclass inheriting from the base API client class.
2
export function useDataFetcher(client = new BaseApiClient())
Defines a Vue composable taking an OOP dependency with a default production instance.
3
const { data, load } = useDataFetcher(new MockApiClient());
Injects the mock class instance into the composable during test setup.
4
expect(data.value).toEqual(['mock-alpha', 'mock-beta']);
Verifies that Vue's ref updated its value asynchronously with mock data.