Vue CLI has built-in options for unit testing with Jest or Mocha that works out of the box. We also have the official Vue Test Utils which provides more detailed guidance for custom setups.
You don’t have to do anything special in your components to make them testable. Export the raw options:
<template> <span>{{ message }}</span> </template> <script> export default { data () { return { message: 'hello!' } }, created () { this.message = 'bye!' } } </script>
Then import the component options along with Vue, and you can make many common assertions (here we are using Jasmine/Jest style expect
assertions just as an example):
// Import Vue and the component being tested import Vue from 'vue' import MyComponent from 'path/to/MyComponent.vue' // Here are some Jasmine 2.0 tests, though you can // use any test runner / assertion library combo you prefer describe('MyComponent', () => { // Inspect the raw component options it('has a created hook', () => { expect(typeof MyComponent.created).toBe('function') }) // Evaluate the results of functions in // the raw component options it('sets the correct default data', () => { expect(typeof MyComponent.data).toBe('function') const defaultData = MyComponent.data() expect(defaultData.message).toBe('hello!') }) // Inspect the component instance on mount it('correctly sets the message when created', () => { const vm = new Vue(MyComponent).$mount() expect(vm.message).toBe('bye!') }) // Mount an instance and inspect the render output it('renders the correct message', () => { const Constructor = Vue.extend(MyComponent) const vm = new Constructor().$mount() expect(vm.$el.textContent).toBe('bye!') }) })
A component’s render output is primarily determined by the props it receives. If a component’s render output solely depends on its props it becomes straightforward to test, similar to asserting the return value of a pure function with different arguments. Take a simplified example:
<template> <p>{{ msg }}</p> </template> <script> export default { props: ['msg'] } </script>
You can assert its render output with different props using the propsData
option:
import Vue from 'vue' import MyComponent from './MyComponent.vue' // helper function that mounts and returns the rendered text function getRenderedText (Component, propsData) { const Constructor = Vue.extend(Component) const vm = new Constructor({ propsData: propsData }).$mount() return vm.$el.textContent } describe('MyComponent', () => { it('renders correctly with different props', () => { expect(getRenderedText(MyComponent, { msg: 'Hello' })).toBe('Hello') expect(getRenderedText(MyComponent, { msg: 'Bye' })).toBe('Bye') }) })
Since Vue performs DOM updates asynchronously, assertions on DOM updates resulting from state change will have to be made in a Vue.nextTick
callback:
// Inspect the generated HTML after a state update it('updates the rendered message when vm.message updates', done => { const vm = new Vue(MyComponent).$mount() vm.message = 'foo' // wait a "tick" after state change before asserting DOM updates Vue.nextTick(() => { expect(vm.$el.textContent).toBe('foo') done() }) })
For more in-depth information on unit testing in Vue, check out Vue Test Utils and our cookbook entry about unit testing vue components.
© 2013–present Yuxi Evan You
Licensed under the MIT License.
https://vuejs.org/v2/guide/unit-testing.html