0
0
Vueframework~5 mins

Testing async behavior in Vue

Choose your learning style9 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.