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
9import 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
19import 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
5shallowMount(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
5shallowMount(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
7shallowMount(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
7shallowMount(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
16import 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
7const $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
18import { 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
10const 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
6import 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
14const 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
23const 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 | import { createLocalVue, shallowMount } from '@vue/test-utils' |
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
10import { 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
12import { 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.