javascript / intermediate
Snippet
Verifying Asynchronous Data Fetching States with flushPromises in Component Tests
When testing components performing asynchronous operations inside setup or lifecycle hooks, simple nextTick calls may not resolve all pending microtasks. flushPromises ensures all unresolved Promises, HTTP mocks, and subsequent reactive DOM updates settle before running test assertions.
snippet.js
javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import { mount, flushPromises } from '@vue/test-utils';import { describe, it, expect, vi } from 'vitest';import UserProfile from './UserProfile.vue';describe('UserProfile async loading', () => {it('transitions from pending skeleton to resolved user name', async () => {vi.spyOn(global, 'fetch').mockResolvedValueOnce({ok: true,json: async () => ({ id: 42, name: 'Alice' })});const wrapper = mount(UserProfile);expect(wrapper.find('[data-test="loader"]').exists()).toBe(true);await flushPromises();expect(wrapper.find('[data-test="username"]').text()).toBe('Alice');expect(wrapper.find('[data-test="loader"]').exists()).toBe(false);});});
vue
Breakdown
1
vi.spyOn(global, 'fetch').mockResolvedValueOnce({
Mocks the native global fetch API to simulate a successful asynchronous HTTP response.
2
expect(wrapper.find('[data-test="loader"]').exists()).toBe(true);
Asserts that the initial loading indicator is rendered while the promise is still pending.
3
await flushPromises();
Flushes all microtasks and queued promises in the event loop before testing the final UI state.