Wrapper

Vue Test Utils 是一个基于包裹器的 API。

一个 Wrapper 是一个包括了一个挂载组件或 vnode,以及测试该组件或 vnode 的方法。

属性

vm

Component (只读):这是该 Vue 实例。你可以通过 wrapper.vm 访问一个实例所有的方法和属性。这只存在于 Vue 组件包裹器或绑定了 Vue 组件包裹器的 HTMLElement 中。

element

HTMLElement (只读):包裹器的根 DOM 节点

options

options.attachedToDocument

Boolean (只读):如果组件在渲染之后被添加到了文档上则为 true

selector

Selector: 被 find()findAll() 创建这个 wrapper 时使用的选择器。

方法

attributes

Returns Wrapper DOM node attribute object. If key is provided, the value for the key will be returned.

  • Arguments:

    • {string} key optional
  • Returns: {[attribute: string]: any} | string

  • Example:

import { mount } from '@vue/test-utils'
import Foo from './Foo.vue'

const wrapper = mount(Foo)
expect(wrapper.attributes().id).toBe('foo')
expect(wrapper.attributes('id')).toBe('foo')

classes

Return Wrapper DOM node classes.

Returns an Array of class names or a boolean if a class name is provided.

  • Arguments:

    • {string} className optional
  • Returns: Array<{string}> | boolean

  • Example:

import { mount } from '@vue/test-utils'
import Foo from './Foo.vue'

const wrapper = mount(Foo)
expect(wrapper.classes()).toContain('bar')
expect(wrapper.classes('bar')).toBe(true)

contains

Assert Wrapper contains an element or component matching selector.

  • Arguments:

    • {string|Component} selector
  • Returns: {boolean}

  • Example:

import { mount } from '@vue/test-utils'
import Foo from './Foo.vue'
import Bar from './Bar.vue'

const wrapper = mount(Foo)
expect(wrapper.contains('p')).toBe(true)
expect(wrapper.contains(Bar)).toBe(true)

destroy

Destroys a Vue component instance.

  • Example:
import { mount } from '@vue/test-utils'
import sinon from 'sinon'

const spy = sinon.stub()
mount({
  render: null,
  destroyed() {
    spy()
  }
}).destroy()
expect(spy.calledOnce).toBe(true)

if either the attachTo or attachToDocument option caused the component to mount to the document, the component DOM elements will also be removed from the document.

For functional components, destroy only removes the rendered DOM elements from the document.

emitted

Return an object containing custom events emitted by the Wrapper vm.

  • Returns: { [name: string]: Array<Array<any>> }

  • Example:

import { mount } from '@vue/test-utils'

test('emit demo', async () => {
  const wrapper = mount(Component)

  wrapper.vm.$emit('foo')
  wrapper.vm.$emit('foo', 123)

  await wrapper.vm.$nextTick() // Wait until $emits have been handled

  /*
  wrapper.emitted() returns the following object:
  {
    foo: [[], [123]]
  }
  */

  // assert event has been emitted
  expect(wrapper.emitted().foo).toBeTruthy()

  // assert event count
  expect(wrapper.emitted().foo.length).toBe(2)

  // assert event payload
  expect(wrapper.emitted().foo[1]).toEqual([123])
})

You can also write the above as follows:

// assert event has been emitted
expect(wrapper.emitted('foo')).toBeTruthy()

// assert event count
expect(wrapper.emitted('foo').length).toBe(2)

// assert event payload
expect(wrapper.emitted('foo')[1]).toEqual([123])

The .emitted() method returns the same object every time it is called, not a new one, and so the object will update when new events are fired:

const emitted = wrapper.emitted()

expect(emitted.foo.length).toBe(1)

// do something to make `wrapper` emit the "foo" event

expect(emitted.foo.length).toBe(2)

emittedByOrder

Deprecation warning

emittedByOrder is deprecated and will be removed in future releases.

Use wrapper.emitted instead.

Return an Array containing custom events emitted by the Wrapper vm.

  • Returns: Array<{ name: string, args: Array<any> }>

  • Example:

import { mount } from '@vue/test-utils'

const wrapper = mount(Component)

wrapper.vm.$emit('foo')
wrapper.vm.$emit('bar', 123)

/*
wrapper.emittedByOrder() returns the following Array:
[
  { name: 'foo', args: [] },
  { name: 'bar', args: [123] }
]
*/

// assert event emit order
expect(wrapper.emittedByOrder().map(e => e.name)).toEqual(['foo', 'bar'])

exists

Assert Wrapper or WrapperArray exists.

Returns false if called on an empty Wrapper or WrapperArray.

  • Returns: {boolean}

  • Example:

import { mount } from '@vue/test-utils'
import Foo from './Foo.vue'

const wrapper = mount(Foo)
expect(wrapper.exists()).toBe(true)
expect(wrapper.find('does-not-exist').exists()).toBe(false)
expect(wrapper.findAll('div').exists()).toBe(true)
expect(wrapper.findAll('does-not-exist').exists()).toBe(false)

find

Deprecation warning

Using find to search for a Component is deprecated and will be removed. Use findComponent instead.

Returns Wrapper of first DOM node or Vue component matching selector.

Use any valid DOM selector (uses querySelector syntax).

  • Arguments:

    • {string} selector
  • Returns: {Wrapper}

  • Example:

import { mount } from '@vue/test-utils'
import Foo from './Foo.vue'
import Bar from './Bar.vue'

const wrapper = mount(Foo)

const div = wrapper.find('div')
expect(div.exists()).toBe(true)

const byId = wrapper.find('#bar')
expect(byId.element.id).toBe('bar')
  • Note:

    • You may chain find calls together:
const button = wrapper.find({ ref: 'testButton' })
expect(button.find('.icon').exists()).toBe(true)

See also: get.

findAll

Deprecation warning

Using findAll to search for Components is deprecated and will be removed. Use findAllComponents instead.

Returns a WrapperArray.

Use any valid selector.

  • Arguments:

    • {string|Component} selector
  • Returns: {WrapperArray}

  • Example:

import { mount } from '@vue/test-utils'
import Foo from './Foo.vue'
import Bar from './Bar.vue'

const wrapper = mount(Foo)

const div = wrapper.findAll('div').at(0)
expect(div.is('div')).toBe(true)

const bar = wrapper.findAll(Bar).at(0) // Deprecated usage
expect(bar.is(Bar)).toBe(true)

findComponent

Returns Wrapper of first matching Vue component.

  • Arguments:

    • {Component|ref|name} selector
  • Returns: {Wrapper}

  • Example:

import { mount } from '@vue/test-utils'
import Foo from './Foo.vue'
import Bar from './Bar.vue'

const wrapper = mount(Foo)

const bar = wrapper.findComponent(Bar) // => finds Bar by component instance
expect(bar.exists()).toBe(true)
const barByName = wrapper.findComponent({ name: 'bar' }) // => finds Bar by `name`
expect(barByName.exists()).toBe(true)
const barRef = wrapper.findComponent({ ref: 'bar' }) // => finds Bar by `ref`
expect(barRef.exists()).toBe(true)

findAllComponents

Returns a WrapperArray of all matching Vue components.

  • Arguments:

    • {Component|ref|name} selector
  • Returns: {WrapperArray}

  • Example:

import { mount } from '@vue/test-utils'
import Foo from './Foo.vue'
import Bar from './Bar.vue'

const wrapper = mount(Foo)
const bar = wrapper.findAllComponents(Bar).at(0)
expect(bar.exists()).toBeTruthy()
const bars = wrapper.findAllComponents(Bar)
expect(bar).toHaveLength(1)

html

Returns HTML of Wrapper DOM node as a string.

  • Returns: {string}

  • Example:

import { mount } from '@vue/test-utils'
import Foo from './Foo.vue'

const wrapper = mount(Foo)
expect(wrapper.html()).toBe('<div><p>Foo</p></div>')

get

Works just like find but will throw an error if nothing matching the given selector is found. You should use find when searching for an element that may not exist. You should use this method when getting an element that should exist and it will provide a nice error message if that is not the case.

import { mount } from '@vue/test-utils'

const wrapper = mount(Foo)

// similar to `wrapper.find`.
// `get` will throw an error if an element is not found. `find` will do nothing.
expect(wrapper.get('.does-exist'))

expect(() => wrapper.get('.does-not-exist'))
  .to.throw()
  .with.property(
    'message',
    'Unable to find .does-not-exist within: <div>the actual DOM here...</div>'
  )

is

Deprecation warning

Using is to assert that DOM node or vm matches selector is deprecated and will be removed.

Consider a custom matcher such as those provided in jest-dom. or for DOM element type assertion use native Element.tagName instead.

To keep these tests, a valid replacement for:

  • is('DOM_SELECTOR') is a assertion of wrapper.element.tagName.
  • is('ATTR_NAME') is a truthy assertion of wrapper.attributes('ATTR_NAME').
  • is('CLASS_NAME') is a truthy assertion of wrapper.classes('CLASS_NAME').

When using with findComponent, access the DOM element with findComponent(Comp).element

Assert Wrapper DOM node or vm matches selector.

  • Arguments:

    • {string|Component} selector
  • Returns: {boolean}

  • Example:

import { mount } from '@vue/test-utils'
import Foo from './Foo.vue'

const wrapper = mount(Foo)
expect(wrapper.is('div')).toBe(true)

isEmpty

Deprecation warning

isEmpty is deprecated and will be removed in future releases.

Consider a custom matcher such as those provided in jest-dom.

When using with findComponent, access the DOM element with findComponent(Comp).element

Assert Wrapper does not contain child node.

  • Returns: {boolean}

  • Example:

import { mount } from '@vue/test-utils'
import Foo from './Foo.vue'

const wrapper = mount(Foo)
expect(wrapper.isEmpty()).toBe(true)

isVisible

Deprecation warning

isVisible is deprecated and will be removed in future releases.

Consider a custom matcher such as those provided in jest-dom.

When using with findComponent, access the DOM element with findComponent(Comp).element

Assert Wrapper is visible.

Returns false if an ancestor element has display: none or visibility: hidden style.

This can be used to assert that a component is hidden by v-show.

  • Returns: {boolean}

  • Example:

import { mount } from '@vue/test-utils'
import Foo from './Foo.vue'

const wrapper = mount(Foo)
expect(wrapper.isVisible()).toBe(true)
expect(wrapper.find('.is-not-visible').isVisible()).toBe(false)

isVueInstance

Deprecation warning

isVueInstance is deprecated and will be removed in future releases.

Tests relying on the isVueInstance assertion provide little to no value. We suggest replacing them with purposeful assertions.

To keep these tests, a valid replacement for isVueInstance() is a truthy assertion of wrapper.find(...).vm.

Assert Wrapper is Vue instance.

  • Returns: {boolean}

  • Example:

import { mount } from '@vue/test-utils'
import Foo from './Foo.vue'

const wrapper = mount(Foo)
expect(wrapper.isVueInstance()).toBe(true)

name

Deprecation warning

name is deprecated and will be removed in future releases.

Returns component name if Wrapper contains a Vue instance, or the tag name of Wrapper DOM node if Wrapper does not contain a Vue instance.

  • Returns: {string}

  • Example:

import { mount } from '@vue/test-utils'
import Foo from './Foo.vue'

const wrapper = mount(Foo)
expect(wrapper.name()).toBe('Foo')
const p = wrapper.find('p')
expect(p.name()).toBe('p')

props

Return Wrapper vm props object. If key is provided, the value for the key will be returned.

Note the Wrapper must contain a Vue instance.

  • Arguments:

    • {string} key optional
  • Returns: {[prop: string]: any} | any

  • Example:

import { mount } from '@vue/test-utils'
import Foo from './Foo.vue'

const wrapper = mount(Foo, {
  propsData: {
    bar: 'baz'
  }
})
expect(wrapper.props().bar).toBe('baz')
expect(wrapper.props('bar')).toBe('baz')

setChecked

Sets checked value for input element of type checkbox or radio and updates v-model bound data.

  • Arguments:

    • {Boolean} checked (default: true)
  • Example:

import { mount } from '@vue/test-utils'
import Foo from './Foo.vue'

const wrapper = mount(Foo)
const radioInput = wrapper.find('input[type="radio"]')
radioInput.setChecked()
  • Note:

When you try to set the value to state via v-model by radioInput.element.checked = true; radioInput.trigger('input'), v-model is not triggered. v-model is triggered by change event.

checkboxInput.setChecked(checked) is an alias of the following code.

checkboxInput.element.checked = checked
checkboxInput.trigger('click')
checkboxInput.trigger('change')

setData

Sets Wrapper vm data.

setData works by recursively calling Vue.set.

Note the Wrapper must contain a Vue instance.

  • Arguments:

    • {Object} data
  • Example:

import { mount } from '@vue/test-utils'
import Foo from './Foo.vue'

const wrapper = mount(Foo)
wrapper.setData({ foo: 'bar' })
expect(wrapper.vm.foo).toBe('bar')

setMethods

Deprecation warning

setMethods is deprecated and will be removed in future releases.

There's no clear path to replace setMethods, because it really depends on your previous usage. It easily leads to flaky tests that rely on implementation details, which is discouraged.

We suggest rethinking those tests.

To stub a complex method extract it from the component and test it in isolation. To assert that a method is called, use your test runner to spy on it.

Sets Wrapper vm methods and forces update.

Note the Wrapper must contain a Vue instance.

  • Arguments:

    • {Object} methods
  • Example:

import { mount } from '@vue/test-utils'
import sinon from 'sinon'
import Foo from './Foo.vue'

const wrapper = mount(Foo)
const clickMethodStub = sinon.stub()

wrapper.setMethods({ clickMethod: clickMethodStub })
wrapper.find('button').trigger('click')
expect(clickMethodStub.called).toBe(true)

setProps

  • Arguments:

    • {Object} props
  • Usage:

Sets Wrapper vm props and forces update.

Note the Wrapper must contain a Vue instance.

import { mount } from '@vue/test-utils'
import Foo from './Foo.vue'

const wrapper = mount(Foo)
wrapper.setProps({ foo: 'bar' })
expect(wrapper.vm.foo).toBe('bar')

You can also pass a propsData object, which will initialize the Vue instance with passed values.

// Foo.vue
export default {
  props: {
    foo: {
      type: String,
      required: true
    }
  }
}
import { mount } from '@vue/test-utils'
import Foo from './Foo.vue'

const wrapper = mount(Foo, {
  propsData: {
    foo: 'bar'
  }
})

expect(wrapper.vm.foo).toBe('bar')

setSelected

Selects an option element and updates v-model bound data.

  • Example:
import { mount } from '@vue/test-utils'
import Foo from './Foo.vue'

const wrapper = mount(Foo)
const options = wrapper.find('select').findAll('option')

options.at(1).setSelected()
  • Note:

When you try to set the value to state via v-model by option.element.selected = true; parentSelect.trigger('input'), v-model is not triggered. v-model is triggered by change event.

option.setSelected() is an alias of the following code.

option.element.selected = true
parentSelect.trigger('change')

setValue

Sets value of a text-control input or select element and updates v-model bound data.

  • Arguments:

    • {any} value
  • Example:

import { mount } from '@vue/test-utils'
import Foo from './Foo.vue'

const wrapper = mount(Foo)

const textInput = wrapper.find('input[type="text"]')
textInput.setValue('some value')

const select = wrapper.find('select')
select.setValue('option value')

// requires <select multiple>
const multiselect = wrapper.find('select')
multiselect.setValue(['value1', 'value3'])
  • Note:

    • textInput.setValue(value) is an alias of the following code.
    textInput.element.value = value
    textInput.trigger('input')
    
    • select.setValue(value) is an alias of the following code.
    select.element.value = value
    select.trigger('change')
    

text

Returns text content of Wrapper.

  • Returns: {string}

  • Example:

import { mount } from '@vue/test-utils'
import Foo from './Foo.vue'

const wrapper = mount(Foo)
expect(wrapper.text()).toBe('bar')

trigger

Triggers an event asynchronously on the Wrapper DOM node.

trigger takes an optional options object. The properties in the options object are added to the Event. trigger returns a Promise, which when resolved, guarantees the component is updated. trigger only works with native DOM events. To emit a custom event, use wrapper.vm.$emit('myCustomEvent')

  • Arguments:

    • {string} eventType required
    • {Object} options optional
  • Example:

import { mount } from '@vue/test-utils'
import sinon from 'sinon'
import Foo from './Foo'

test('trigger demo', async () => {
  const clickHandler = sinon.stub()
  const wrapper = mount(Foo, {
    propsData: { clickHandler }
  })

  await wrapper.trigger('click')

  await wrapper.trigger('click', {
    button: 0
  })

  await wrapper.trigger('click', {
    ctrlKey: true // For testing @click.ctrl handlers
  })

  expect(clickHandler.called).toBe(true)
})
  • Setting the event target:

Under the hood, trigger creates an Event object and dispatches the event on the Wrapper element.

It's not possible to edit the target value of an Event object, so you can't set target in the options object.

To add an attribute to the target, you need to set the value of the Wrapper element before calling trigger. You can do this with the element property.

const input = wrapper.find('input')
input.element.value = 100
input.trigger('click')