This book is written for Vue.js 3 and Vue Test Utils v2.
Find the Vue.js 2 version here.
Two ways to render
vue-test-utils
provides two ways to render, or mount a component - mount
and shallowMount
. A component mounted using either of these methods returns a wrapper
, which is an object containing the Vue component, plus some useful methods for testing.
Let’s start off with two simple components:
const Child = Vue.component("Child", {
name: "Child",
template: "<div>Child component</div>"
})
const Parent = Vue.component("Parent", {
name: "Parent",
template: "<div><child /></div>"
})
Let’s start off by rendering Child
and calling the html
method vue-test-utils
provides to inspect the markup.
const shallowWrapper = shallowMount(Child)
const mountWrapper = mount(Child)
console.log(shallowWrapper.html())
console.log(mountWrapper.html())
Both mountWrapper.html()
and shallowWrapper.html()
yield the following output:
<div>Child component</div>
No difference here. How about with Parent
?
const shallowWrapper = shallowMount(Parent)
const mountWrapper = mount(Parent)
console.log(shallowWrapper.html())
console.log(mountWrapper.html())
mountWrapper.html()
now yields:
<div><div>Child component</div></div>
Which is the completely rendered markup of Parent
and Child
. shallowWrapper.html()
, on the other hand, produces this:
<div><vuecomponent-stub></vuecomponent-stub></div>
The place where <Child />
should be has been replaced by <vuecomponent-stub />
. shallowMount
renders regular html elements, but replaces Vue components with a stub.
A stub is kind of a “fake” object that stands in for a real one.
This can be useful. Imagine you want to test your App.vue
component, that looks like this:
<template>
<div>
<h1>My Vue App</h1>
<fetch-data />
</div>
</template>
And we want to test <h1>My Vue App</h1>
is rendered correctly. We also have a <fetch-data>
component, that makes a request to an external API in its mounted
lifecycle hook.
If we use mount
, although all we want to do is assert some text is rendered, <fetch-data />
will make an API request. This will make our test slow and prone to failure. So, we stub out external dependencies. By using shallowMount
, <fetch-data />
will be replaced with a <vuecomponent-stub />
, and the API call will not be initiated.
As a rule of thumb, you should try to use mount
, since that will more closely resemble your components and how they will appear in a real environment. That said, if you are having trouble with many API requests firing, or supplying the necessary dependencies to render your component, you can use shallowMount
.: