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.: