Testing Vue Components with render, mount, and shallowMount

Devanshu Agarwal

Written by Devanshu Agarwal /

Introduction

Vue.js provides several methods for testing components, including render, mount, and shallowMount. In this article, we'll discuss the differences between these methods and when to use each one.

Initial Setup

Now, let's create two components: ParentComponent.vue and ChildComponent.vue. The ParentComponent component includes the ChildComponent component.

ParentComponent.vue:

JSX
<template>
  <div>
    <p>Parent component</p>
    <ChildComponent />
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue'

export default {
  name: 'ParentComponent',
  components: {
    ChildComponent
  }
}
</script>

ChildComponent.vue:

JSX
<template>
  <div>
    <p>Child component</p>
  </div>
</template>

<script>
export default {
  name: 'ChildComponent'
}
</script>

With these components in place, we're now ready to start testing!

render

The render function is the simplest method for testing components in Vue.js. It takes a component and returns a virtual DOM representation of that component, without actually mounting it to the document.

This is useful for testing the output of a component, without having to worry about any child components or DOM interactions.

Here's an example of using render to test a component:

JSX
import { render } from '@vue/test-utils'
import ParentComponent from './ParentComponent.vue'

describe('ParentComponent', () => {
  it('renders correctly', () => {
    const wrapper = render(ParentComponent)
    expect(wrapper.html()).toContain('<p>Parent component</p>')
    expect(wrapper.html()).not.toContain('<p>Child component</p>')
  })
})

The output of the html method in this case will be:

<div>
  <p>Parent component</p>
</div>

This shows that the child component is not included in the output of the render function, just like with shallowMount. The render function provides a way to render a component for testing purposes, but does not include any of its child components in the output.

shallowMount

The shallowMount function is similar to render, but it mounts the component to a shallow virtual DOM. This means that the component will be mounted, but any child components will not be rendered.

Here's an example of using shallowMount to test a parent-child component:

JSX
import { shallowMount } from '@vue/test-utils'
import ParentComponent from './ParentComponent.vue'

describe('ParentComponent', () => {
  it('renders correctly', () => {
    const wrapper = shallowMount(ParentComponent)
    expect(wrapper.html()).toContain('<p>Parent component</p>')
    expect(wrapper.html()).not.toContain('<p>Child component</p>')
  })
})

The output of the html method in this case will be:

<div>
  <p>Parent component</p>
</div>

In this example, the parent component includes a child component. When we use shallowMount to render the parent component, the output will only include the parent component, and not the child component.

mount

The mount function is the most comprehensive method for testing components in Vue.js. It mounts the component to a full virtual DOM, including all child components.

Here's an example of using mount to test a parent-child component:

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

describe('ParentComponent', () => {
  it('renders correctly', () => {
    const wrapper = mount(ParentComponent)
    expect(wrapper.html()).toContain('<p>Parent component</p>')
    expect(wrapper.html()).toContain('<p>Child component</p>')
  })
})

The output of the html method in this case will be:

<div>
  <p>Parent component</p>
  <div>
    <p>Child component</p>
  </div>
</div>

In this example, the parent component includes a child component. When we use mount to render the parent component, the output will include both the parent component and the child component, making it possible to test the interactions between parent and child components.

Render vs. ShallowMount

The render and shallowMount looks similar let's check the comparison closely.

The render function is used to render a component without rendering its child components. This makes it useful for testing simple components that don't have any child components or complex interactions with the DOM.

On the other hand, the shallowMount function is used to render a component, including its child components. However, the child components are only "shallowly" rendered, meaning that their behavior is mocked, and their template is not actually rendered. This makes it possible to test the interactions between the parent component and its child components, without rendering the child components themselves.

In short, if you want to test a component in isolation, use render. If you want to test a component with its child components, use shallowMount.

Render vs. ShallowMount: Methods

The render function provides a simple set of methods for testing components. These methods include:

  • find: Finds an element or elements in the component's template.
  • text: Returns the text content of an element.
  • html: Returns the HTML content of an element.
  • attributes: Returns the attributes of an element.

The shallowMount function provides a more comprehensive set of methods for testing components, including the methods provided by render, as well as additional methods for testing the behavior of child components:

  • setData: Sets the data for the component and re-renders the component.
  • setProps: Sets the props for the component and re-renders the component.
  • trigger: Triggers an event on an element.
  • emitted: Returns the events that have been emitted by the component. In summary, if you need more advanced testing features, such as triggering events or testing the behavior of child components, use shallowMount. If you only need to test simple properties of a component, such as its text or HTML content, use render.

Conclusion

When testing Vue components, it's important to choose the right method depending on the requirements of your test. The render function is useful for testing simple components, without any child components or DOM interactions. The shallowMount function is useful for testing parent-child components, without rendering any child components. And finally, the mount function is the most comprehensive method for testing components, allowing you to test both parent and child components and the interactions between them.

In conclusion, render, shallowMount, and mount are powerful tools that make it easy to write comprehensive tests for Vue components. Whether you're testing a simple component, or a complex parent-child component, these methods will help you ensure that your code works as expected.