@vue/test-utils 2.5.1 (Vue 3)
Prepared source: input/source, version 2.5.1 (package.json:3).
Requires Vue 3.x and @vue/compiler-dom 3.x as peers; @vue/server-renderer 3.x is an optional peer needed only for renderToString (package.json:73-81).
Test-runner agnostic (Vitest, Jest, others). Needs a browser-like DOM environment (jsdom or happy-dom).
Install: npm install @vue/test-utils --save-dev
Quick start
import { mount } from '@vue/test-utils'
import Counter from './Counter.vue'
test('increments', async () => {
const wrapper = mount(Counter, { props: { start: 1 } })
await wrapper.find('button').trigger('click')
expect(wrapper.text()).toContain('2')
})
Public API surface
Exports from dist/src/index.d.ts:13:
| Export | Kind | Use |
|---|---|---|
mount | function | Mount a component, returns VueWrapper (dist/src/mount.d.ts:17) |
shallowMount | function | Same as mount with all child components stubbed (dist/src/mount.d.ts:22) |
renderToString | function | SSR-render a component to a string, Promise<string> (dist/src/renderToString.d.ts:4) |
flushPromises | function | Await pending non-Vue promises (mocked API calls, timers) (dist/src/utils/flushPromises.d.ts:1) |
enableAutoUnmount(hook) | function | Unmount all wrappers via a test hook (dist/src/utils/autoUnmount.d.ts:4) |
disableAutoUnmount | function | Stop auto unmounting (dist/src/utils/autoUnmount.d.ts:3) |
VueWrapper | class | Wrapper around a mounted component instance (dist/src/vueWrapper.d.ts:5) |
DOMWrapper | class | Wrapper around a DOM element; new DOMWrapper(document.body) (dist/src/domWrapper.d.ts:4) |
RouterLinkStub | component | Stub for <router-link> (dist/src/components/RouterLinkStub.d.ts:1) |
config | object | Shared default mount options and wrapper plugins (dist/src/config.d.ts:32) |
createWrapperError | function | Internal; produces the error wrapper returned by find misses |
Core rules
awaitevery method that returns a promise:trigger,setValue,setProps,setData,renderToString,flushPromises. Withoutawait, assertions run before the DOM updates.- Use
get()/getComponent()when the element must exist; they throw on miss. Usefind()/findComponent()only when absence is a valid outcome; they return an error wrapper whoseexists()isfalse. find()accepts CSS selectors only. To locate a child component usefindComponent(Component),findComponent({ name: 'Foo' }),findComponent({ ref: 'foo' }), or a CSS selector.- Register
enableAutoUnmount(afterEach)once in test setup to prevent state leaks between tests. - Use
flushPromises()for promises Vue does not track (mocked HTTP clients,setTimeout). wrapper.vmonly reliably exposes what the component exposes: options-API state,defineExpose()bindings (since 2.5.0, PR #2927), orsetup()return values.
import { enableAutoUnmount } from '@vue/test-utils'
import { afterEach } from 'vitest'
enableAutoUnmount(afterEach)
Version notes: 2.4.10 -> 2.5.1
- BREAKING (2.5.0): class component support removed. Mount Vue components defined with
defineComponent, options objects, or<script setup>SFCs. https://github.com/vuejs/test-utils/releases/tag/v2.5.0 - Fix (2.5.0):
emitted()history of child components is cleared when they unmount. Assert events before unmounting. https://github.com/vuejs/test-utils/pull/2898 - Fix (2.5.0):
defineExposebindings are visible onfindComponent(...).vm. https://github.com/vuejs/test-utils/pull/2927 - Fix (2.4.11):
setData()works correctly for components mixingsetup()anddata(). https://github.com/vuejs/test-utils/releases/tag/v2.4.11 - Fix (2.4.11):
trigger('keydown')sets a spec-compliantevent.code. https://github.com/vuejs/test-utils/pull/2850 - Type (2.4.11):
GlobalMountOptionsis exported. https://github.com/vuejs/test-utils/pull/2851
Earlier v2 milestones still relevant
renderToStringadded in 2.3.0 for SSR testing. https://github.com/vuejs/test-utils/releases/tag/v2.3.0html({ raw: true }), directive stubs (vName: true), and arraysetValuefor multiselect added in 2.2.0. https://github.com/vuejs/test-utils/releases/tag/v2.2.0enableAutoUnmount/disableAutoUnmountreplaced v1enableAutoDestroy. https://github.com/vuejs/test-utils/releases/tag/v2.0.0-rc.16propsDatastill works but is deprecated; useprops(dist/src/types.d.ts:33-35).stubsaccepts a record ({ Foo: true }) or an array of names (['Foo']) (dist/src/types.d.ts:80).
Migrating from v1 (Vue 2)
Full table: migration reference, official guide https://test-utils.vuejs.org/migration/
propsData->props;createLocalVueremoved ->global.plugins/global.mixinsmocks,stubs,provide,directivesmoved underglobaldestroy()->unmount();findAll().at(i)->findAll()[i](returns an array)createWrapper()removed ->new DOMWrapper(el)setChecked/setSelectedremoved -> merged intosetValuefind()no longer finds components by name; usefindComponentshallowMountno longer renders default slot content of stubs; restore withconfig.global.renderStubDefaultSlot = true- Removed:
is,isEmpty,isVueInstance,name,setMethods,contains,scopedSlots(merged intoslots)
Best practices
- Prefer
mountwith targetedglobal.stubsovershallowMount. Shallow tests assert structure, not behavior, and stubbed children hide real interactions. https://test-utils.vuejs.org/guide/advanced/stubs-shallow-mount - If you do stub broadly, set
config.global.renderStubDefaultSlot = trueso default slot content of stubs still renders (dist/src/types.d.ts:125-131). - Stub directives with the
vNamekey:global.stubs: { vTooltip: true }or pass a replacement directive object. <transition>and<transition-group>are stubbed by default (dist/src/types.d.ts:120-124); custom transition stubs are supported.- Pass inject values through
global.provide, matching production injection. For typed injection keys, wrap the key:provide: { [injectionKey as symbol]: value }. - Test composables by mounting a minimal host component and reading state from
wrapper.vm. - Wrap components with
async setup()in a<Suspense>host before mounting. - For
<Teleport>, either stub it (global.stubs: { teleport: true }) or create the target element inbeforeEachand query it withdocument.querySelector. https://test-utils.vuejs.org/guide/advanced/teleport - Use
RouterLinkStubwhen testing around<router-link>without installing a router:global.stubs: { 'router-link': RouterLinkStub }.
References
- Mounting options and config: every
mount/shallowMount/renderToStringoption,global.*, and theconfigobject. - Wrapper API: every
VueWrapper/DOMWrappermethod with signatures. - Migration v1 -> v2: full option and method mapping plus 2.5.x changes.
- Testing recipes: forms,
v-model, emitted events, router, Vuex/Pinia, Suspense, Teleport, SSR.