javascript / expert
Snippet
Asserting Async Svelte Store Transitions with Deferred Promises
When unit testing asynchronous custom Svelte stores, manual controlling of Promise resolution is key to validating intermediate loading states. Using a deferred Promise closure allows you to capture state snapshots emitted via `subscribe` prior to and immediately after asynchronous data resolution.
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
31
32
33
34
35
import { writable } from 'svelte/store';import { expect, test } from 'vitest';function createAsyncStore(fetcher) {const { subscribe, set } = writable({ data: null, loading: false, error: null });return {subscribe,async load() {set({ data: null, loading: true, error: null });try {const data = await fetcher();set({ data, loading: false, error: null });} catch (err) {set({ data: null, loading: false, error: err.message });}}};}test('emits intermediate loading state during pending fetch resolution', async () => {let resolvePromise;const mockFetcher = () => new Promise(res => { resolvePromise = res; });const store = createAsyncStore(mockFetcher);const states = [];const unsubscribe = store.subscribe(s => states.push(s));const loadPromise = store.load();expect(states.at(-1)).toEqual({ data: null, loading: true, error: null });resolvePromise('success_data');await loadPromise;expect(states.at(-1)).toEqual({ data: 'success_data', loading: false, error: null });unsubscribe();});
svelte
Breakdown
1
const mockFetcher = () => new Promise(res => { resolvePromise = res; });
Exposes the inner resolve callback externally to defer execution on demand.
2
const unsubscribe = store.subscribe(s => states.push(s));
Subscribes to store updates, storing every emitted state snapshot into an array sequence.
3
expect(states.at(-1)).toEqual({ data: null, loading: true, error: null });
Verifies that the store correctly transitioned into a pending loading state prior to promise resolution.
4
resolvePromise('success_data'); await loadPromise;
Fulfills the pending Promise manually and awaits the completion of the store load routine.