Vue-test-utils

Vue-test-utils is an official test tool built into vue. It can load a vue instance and extract and replace its methods, properties, events, etc.

Once you’re familiar with the Vue framework, it’s easy to look at the vue-test-util tool because many of the concepts are the same.

This blog is based on vue-test-utils, the official doc of vue. It tries to explain the ambiguities in some official docs, and also refers to some blogs. It is mainly used for conceptual understanding and explanation of basic usages.

API

Mount

  • Parameters

    • component: Component
    • options: Options
  • Return value: Wrapper

  • options

    • context:Object

      Pass the context to a function-like component, which can only be used for函数式组件

      Example:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      import Foo from './Foo.vue'
      import Bar from './Bar.vue'
      const wrapper = mount(Component, {
      context: {
      props: { show: true },
      children: [Foo, Bar]
      }
      })
      expect(wrapper.is(Component)).toBe(true)
    • slots: Array|Component|string

      An object that provides a slot content for a component. The key name in this object is the corresponding slot name. The key value can be a component, an array of components, a string template, or text.

      Example:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      import Foo from './Foo.vue'

      const bazComponent = {
      name: 'baz-component',
      template: '<p>baz</p>'
      }

      const wrapper = shallowMount(Component, {
      slots: {
      default: [Foo, '<my-component />', 'text'],
      FooBar: Foo,//will match '< slot name = "FooBar"/>'.
      foo: '<div />',
      bar: 'bar',
      baz: bazComponent,
      qux: '<my-component />'
      }
      })

      expect(wrapper.find('div')).toBe(true)

      The description of the official doc here is too simple and may cause ambiguity. If you have doubts about this content, you can check it out.这篇文章

    • scopedSlots

      Provide a component for all作用域插槽 object. Each key corresponds to the name of the slot.

      You can set the name of the prop using the slot-scope attribute:

      1
      2
      3
      4
      5
      shallowMount(Component, {
      scopedSlots: {
      foo: '<p slot-scope="foo">{{foo.index}},{{foo.text}}</p>'
      }
      })

      Otherwise, you can use prop through the’props’ object when the slot is evaluated:

      1
      2
      3
      4
      5
      shallowMount(Component, {
      scopedSlots: {
      default: '<p>{{props.index}},{{props.text}}</p>'
      }
      })

      You can also pass a function with prop as an argument:

      1
      2
      3
      4
      5
      6
      7
      shallowMount(Component, {
      scopedSlots: {
      foo: function(props) {
      return this.$createElement('div', props.index)
      }
      }
      })

      Or you can use JSX. If you write JSX in a method, babel-plugin-transform-vue-jsx will automatically inject’this. $createElement ':

      1
      2
      3
      4
      5
      6
      7
      shallowMount(Component, {
      scopedSlots: {
      foo(props) {
      return <div>{props.text}</div>
      }
      }
      })
    • stubs:{ [name: string]: Component | boolean } | Array

      Stub subcomponents. Can be an array or object of component names to stub. If stubs is an array, each stub is a < ${component name} -stub >.

      Example:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      import Foo from './Foo.vue'

      mount(Component, {
      stubs: ['registered-component']
      })

      shallowMount(Component, {
      stubs: {
      Use a specific implementation as a stub
      'registered-component': Foo,
      //Use create default implementation as stub.
      //The default stub component name here is another-component.
      //The default stub is' < ${the component name of default stub} -stub > '.
      'another-component': true
      }
      })
    • mocks: Object

      Add additional properties to the instance. Useful when faking global injection.

      Example:

      1
      2
      3
      4
      5
      6
      7
      const $route = { path: 'http://www.example-path.com' }
      const wrapper = shallowMount(Component, {
      mocks: {
      $route
      }
      })
      expect(wrapper.vm.$route.path).toBe($route.path)
    • localVue: Vue

      A local copy of Vue created by [‘./createLocalVue.md’] when mounting the component. Installing plugins on this copy prevents the original Vue from being contaminated.

      Example:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      import { createLocalVue, mount } from '@vue/test-utils'
      import VueRouter from 'vue-router'
      import Foo from './Foo.vue'

      const localVue = createLocalVue()
      localVue.use(VueRouter)

      const routes = [{ path: '/foo', component: Foo }]

      const router = new VueRouter({
      routes
      })

      const wrapper = mount(Component, {
      localVue,
      router
      })
      expect(wrapper.vm.$route).toBeInstanceOf(Object)
    • attachToDocument: Boolean

      When set to’true ', the component will be mounted to the DOM during rendering.

      If added to the DOM, you should call’wrapper.destroy () 'at the end of the test to remove the element from the doc and destroy the component instance.

    • attrs: Object

      Sets the $attrs object of the component instance.

    • propsData

      Sets the prop of the component instance when the component is mounted.

      Example:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      const Component = {
      template: '<div>{{ msg }}</div>',
      props: ['msg']
      }
      const wrapper = mount(Component, {
      propsData: {
      msg: 'aBC'
      }
      })
      expect(wrapper.text()).toBe('aBC')

      Tip

      It is worth noting that’propsData 'is actually a Vue API, is not the mount option for Vue Test Utils. It will be extends Processing. Please refer to其它选项

    • listeners: Object

      Sets the $listeners object for the component instance.

    • parentComponent: Object

      Used as the parent component of the mounted component.

      Example:

      1
      2
      3
      4
      5
      6
      import Foo from './Foo.vue'

      const wrapper = shallowMount(Component, {
      parentComponent: Foo
      })
      expect(wrapper.vm.$parent.$options.name).toBe('foo')
    • provide: Object

      Passing properties for injection to the component. Available in provie/inject Learn more.

      Example:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      const Component = {
      inject: ['foo'],
      template: '<div>{{this.foo()}}</div>'
      }

      const wrapper = shallowMount(Component, {
      provide: {
      foo() {
      return 'fooValue'
      }
      }
      })

      expect(wrapper.text()).toBe('fooValue')
    • Other options

      When the options for’mount ‘and’shallowMount’ contain options other than the mount options, they will be passed扩展Override to its component options.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      const Component = {
      template: '<div>{{ foo() }}{{ bar() }}{{ baz() }}</div>',
      methods: {
      foo() {
      return 'a'
      },
      bar() {
      return 'b'
      }
      }
      }
      const options = {
      methods: {
      bar() {
      return 'B'
      },
      baz() {
      return 'C'
      }
      }
      }
      const wrapper = mount(Component, options)
      expect(wrapper.text()).toBe('aBC')

ShallowMount

The usage is the same as mount, but it will give all subcomponents to stub, similar to the effect of filling all subcomponents in the stub property in mount options

render

Render an object as a string and return a cheerio 包裹器

Cheerio is a jQuery-like library for exploring DOM objects in Node.js. Its API and Vue Test Utils Wrapper Similar.

'Render 'is used under the hood vue-server-renderer Render a component as static HTML.

Render is included in the @vue/server-test-utils package.

renderToString

Render a component as HTML.

'renderToString 'is used under the hood vue-server-renderer Render a component as HTML.

selector

Many method parameters contain selectors. A selector can be a CSS selector, a Vue component, or a search option object

createLocalVue

  • ** Return value: **
    • {Component}
  • ** Usage: **

'createLocalVue 'returns a Vue class for you to add components, mix in, and install plugins without polluting the global Vue class.

Can be used through’options.localVue ':

1
2
3
4
5
6
7
8
9
10
11
12
import { createLocalVue, shallowMount } from '@vue/test-utils'
import Foo from './Foo.vue'

const localVue = createLocalVue()
const wrapper = shallowMount(Foo, {
localVue,
mocks: { foo: true }
})
expect(wrapper.vm.foo).toBe(true)

const freshWrapper = shallowMount(Foo)
expect(freshWrapper.vm.foo).toBe(false)

createWrapper(node

  • ** Parameters: **

    • {vm|HTMLElement} node

    • {Object} options
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19

      - `{Boolean} attachedToDocument`

      - ** Return value: **

      - `{Wrapper}`

      - ** Usage: **

      CreateWrapper creates a Wrapper for a mounted Vue instance or an HTML element.

      ```js
      import { createWrapper } from '@vue/test-utils'
      import Foo from './Foo.vue'

      const Constructor = Vue.extend(Foo)
      const vm = new Constructor().$mount()
      const wrapper = createWrapper(vm)
      expect(wrapper.vm.foo).toBe(true)

Wrapper

The above API is to create a vue instance of the wrapper, so after the creation is completed, the wrapper itself also has many interfaces.

The specific will not be repeated here. The general function is similar to the configuration of the wrapper with options. The method of the wrapper can change and obtain certain properties after the wrapper instance is generated. For example, setMethods can change the methods in vue, and trigger can trigger a specified event on a component.

Here we take an example to test the methods in vue in different ways to illustrate its usage:

  • The first is an example of the official doc

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    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)

    It should be noted here that different versions of setMethods are not the same. Some versions of setMethods are a synchronous method. Zoe’s above writing is correct, but some versions are asynchronous methods, so you need to wait for it to take effect. For example:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import { mount } from '@vue/test-utils'
    import sinon from 'sinon'
    import Foo from './Foo.vue'
    import Vue from 'vue';

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

    wrapper.setMethods({ clickMethod: clickMethodStub })
    await Vue.nextTick();
    wrapper.find('button').trigger('click')
    expect(clickMethodStub.called).toBe(true)
  • The second method is to pass an options when creating the wrapper. What is used here is that mount will extend the other options in the options by extending the features in the wrapper. For specific code, please refer to the code in the other options section of options.

Both of the above methods can be combined with sinon to mock the method in a vue instance for testing.

Of course, there are other ways to pass a method into the wrapper, such as context and provide in options.