Bird
Raised Fist0
Vueframework~5 mins

Testing async behavior in Vue

Choose your learning style10 modes available
Introduction

Testing async behavior helps ensure your app works correctly when waiting for data or actions that take time.

When fetching data from a server and you want to check the result.
When waiting for a user action that triggers a delay, like a button click with a timeout.
When testing components that update after a promise resolves.
When verifying loading states before and after async tasks.
When making sure errors from async calls are handled properly.
Syntax
Vue
import { mount } from '@vue/test-utils'
import { nextTick } from 'vue'

test('async test example', async () => {
  const wrapper = mount(MyComponent)
  // trigger async action
  await wrapper.find('button').trigger('click')
  // wait for DOM updates
  await nextTick()
  expect(wrapper.text()).toContain('Loaded')
})

Use async/await to wait for async actions in tests.

nextTick() waits for Vue to update the DOM after state changes.

Examples
Wait for a component method that returns a promise, then wait for DOM update.
Vue
await wrapper.vm.loadData()
await nextTick()
expect(wrapper.text()).toContain('Data loaded')
Simulate a button click that triggers async work, then check the result.
Vue
await wrapper.find('button').trigger('click')
await nextTick()
expect(wrapper.find('.result').exists()).toBe(true)
flushPromises() waits for all pending promises to resolve.
Vue
await flushPromises()
expect(wrapper.text()).toContain('Finished')
Sample Program

This component shows "Loading..." first, then after 100ms changes to "Data loaded". The test waits for this change and checks both states.

Vue
import { defineComponent, ref } from 'vue'

export default defineComponent({
  name: 'AsyncTest',
  setup() {
    const message = ref('Loading...')
    const loadData = async () => {
      await new Promise(resolve => setTimeout(resolve, 100))
      message.value = 'Data loaded'
    }
    loadData()
    return { message }
  },
  template: `<div>{{ message }}</div>`
})

// Test file
import { mount } from '@vue/test-utils'
import { nextTick } from 'vue'
import AsyncTest from './AsyncTest.vue'

test('shows loading then loaded message', async () => {
  const wrapper = mount(AsyncTest)
  expect(wrapper.text()).toBe('Loading...')
  await new Promise(resolve => setTimeout(resolve, 110))
  await nextTick()
  expect(wrapper.text()).toBe('Data loaded')
})
OutputSuccess
Important Notes

Always wait for Vue's DOM updates with nextTick() after async changes.

Use timers or flushPromises() to handle promises in tests.

Keep tests simple and only wait as long as needed to avoid slow tests.

Summary

Testing async behavior means waiting for promises and DOM updates.

Use async/await and nextTick() in Vue tests.

Check both before and after async changes to be sure your component works.

Practice

(1/5)
1. In Vue testing, why do we use await nextTick() after triggering an async update?
easy
A. To wait for Vue to finish updating the DOM after state changes
B. To pause the test indefinitely
C. To reset the component to its initial state
D. To skip the async operation and test synchronously

Solution

  1. Step 1: Understand Vue's DOM update cycle

    Vue batches DOM updates and applies them asynchronously after state changes.
  2. Step 2: Purpose of await nextTick()

    Using await nextTick() waits for Vue to complete these DOM updates before assertions.
  3. Final Answer:

    To wait for Vue to finish updating the DOM after state changes -> Option A
  4. Quick Check:

    nextTick waits for DOM update [OK]
Hint: Remember nextTick waits for DOM updates after async changes [OK]
Common Mistakes:
  • Thinking nextTick pauses test indefinitely
  • Assuming nextTick resets component state
  • Believing nextTick skips async operations
2. Which of the following is the correct way to write an async test function in Vue using Jest?
easy
A. test('async test', () => { someAsyncFunction().then(); });
B. test('async test', () => { await someAsyncFunction(); });
C. test('async test', async () => { await someAsyncFunction(); });
D. test('async test', () => { someAsyncFunction(); });

Solution

  1. Step 1: Identify async test syntax

    Tests using async/await must declare the test function as async to use await inside.
  2. Step 2: Check each option

    test('async test', async () => { await someAsyncFunction(); }); correctly declares the test function async and awaits the async function.
  3. Final Answer:

    test('async test', async () => { await someAsyncFunction(); }); -> Option C
  4. Quick Check:

    Async test functions need async keyword [OK]
Hint: Always add async before test callback to use await [OK]
Common Mistakes:
  • Omitting async keyword before test function
  • Using await outside async function
  • Not waiting for promises to resolve
3. Given this Vue test snippet, what will be the value of wrapper.text() after the test runs?
const wrapper = mount(MyComponent);
await wrapper.find('button').trigger('click');
await nextTick();

Assuming the button click triggers an async state update that changes displayed text from 'Off' to 'On'.
medium
A. 'Off'
B. 'On'
C. '' (empty string)
D. Throws an error

Solution

  1. Step 1: Understand the click triggers async state change

    The button click changes the component's state asynchronously from 'Off' to 'On'.
  2. Step 2: Use await nextTick() to wait for DOM update

    After triggering click, awaiting nextTick ensures DOM reflects the new state.
  3. Final Answer:

    'On' -> Option B
  4. Quick Check:

    Async update + nextTick = updated DOM text [OK]
Hint: Wait nextTick after async event to see updated DOM [OK]
Common Mistakes:
  • Checking DOM before nextTick causes stale text
  • Assuming immediate synchronous update
  • Forgetting to await async events
4. What is wrong with this Vue test code snippet?
test('updates message after async call', async () => {
  const wrapper = mount(MyComponent);
  wrapper.vm.fetchData();
  expect(wrapper.text()).toContain('Loaded');
});
medium
A. Missing await before fetchData call
B. Missing await nextTick() after fetchData
C. Using expect before async update completes
D. All of the above

Solution

  1. Step 1: Identify missing awaits

    The test calls async fetchData without awaiting it, so the update may not finish.
  2. Step 2: Recognize missing nextTick and premature expect

    Without awaiting nextTick, DOM updates may not be applied before expect runs.
  3. Final Answer:

    All of the above -> Option D
  4. Quick Check:

    Await async calls and nextTick before assertions [OK]
Hint: Always await async calls and nextTick before assertions [OK]
Common Mistakes:
  • Not awaiting async methods
  • Not waiting for DOM updates
  • Running assertions too early
5. You have a Vue component that fetches user data asynchronously on mount and displays the user's name. Which test approach correctly verifies the name is shown after the async fetch?
test('displays user name after fetch', async () => {
  const wrapper = mount(UserComponent);
  // What should you do here?
});
hard
A. await flushPromises(); await nextTick(); expect(wrapper.text()).toContain('Alice');
B. expect(wrapper.text()).toContain('Alice');
C. await wrapper.vm.fetchUser(); expect(wrapper.text()).toContain('Alice');
D. wrapper.vm.fetchUser(); expect(wrapper.text()).toContain('Alice');

Solution

  1. Step 1: Wait for all promises to resolve

    Using flushPromises() waits for all pending promises like fetch to finish.
  2. Step 2: Wait for Vue DOM updates

    After promises resolve, await nextTick() ensures DOM updates are applied.
  3. Final Answer:

    await flushPromises(); await nextTick(); expect(wrapper.text()).toContain('Alice'); -> Option A
  4. Quick Check:

    Flush promises + nextTick = reliable async test [OK]
Hint: Flush promises then nextTick before checking DOM [OK]
Common Mistakes:
  • Checking DOM before promises resolve
  • Not waiting for nextTick after async updates
  • Calling async methods without awaiting
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard