0 day streak
javascript / intermediate
Snippet

Unit Testing Vue Composables with Isolated App Context

When unit testing composables that rely on Vue lifecycle hooks or provide/inject context, invoking them inside a helper test harness like withSetup ensures that an active Vue instance is present. This isolates reactivity logic cleanly from UI rendering during test suites.

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
29
30
import { describe, it, expect } from 'vitest';
import { ref, createApp } from 'vue';
export function useCounter(initialValue = 0) {
const count = ref(initialValue);
const increment = () => { count.value++; };
return { count, increment };
}
export function withSetup(composable) {
let result;
const app = createApp({
setup() {
result = composable();
return () => {};
}
});
app.mount(document.createElement('div'));
return [result, app];
}
describe('useCounter', () => {
it('increments count correctly within Vue scope', () => {
const [counterApp, app] = withSetup(() => useCounter(5));
expect(counterApp.count.value).toBe(5);
counterApp.increment();
expect(counterApp.count.value).toBe(6);
app.unmount();
});
});
vue
Breakdown
1
export function withSetup(composable) {
Defines a test harness wrapper to execute composables in a mock Vue app context.
2
const app = createApp({ setup() { result = composable(); return () => {}; } });
Instantiates a minimal application component that triggers the composable inside its setup method.
3
const [counterApp, app] = withSetup(() => useCounter(5));
Executes the composable within the simulated application environment for testing.
4
app.unmount();
Cleans up the mounted test application instance to prevent memory leaks across tests.