w3resource
Vue Tutorial

Unit Testing

The Vue CLI has built-in for unit testing with Mocha or Jest that works out of the box. There are also official Vue Test Utils which provides more detailed guidance for custom setups.

Simple Assertions

We don't have to do anything special in our components to make them testable. We can export the raw options:

<template>
  <span>{{ message }}</span>
</template>

<script>
  export default {
    data () {
      return {
        message: 'hello!'
      }
    },
    created () {
      this.message = 'bye!'
    }
  }
</script>

Then we import the component options along with Vue, and we can make many common assertions (in this case we are using Jest/Jasmine style expect assertions as an example):

// Import Vue as well as the component being tested
```import Vue from 'vue'
import MyComponent from 'path/to/MyComponent.vue'

// these are some Jasmine 2.0 tests, though we can
// use any test runner / assertion library combo we prefer
describe('MyComponent', () => {
  // Inspecting the raw component options
  it('has a created hook', () => {
    expect(typeof MyComponent.created).toBe('function')
  })

  // we 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!')
  })

  // Inspecting the component instance on mount
  it('correctly sets the message when created', () => {
    const vm = new Vue(MyComponent).$mount()
    expect(vm.message).toBe('bye!')
  })

  // we 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!')
  })
})

Writing Testable Components

The props a component receives determines the component's render output. It is straightforward to test a component if its render output solely depends on its props, this is similar to asserting the return value of a pure function with different arguments. A simplified example is shown below:

<template>
  <p>{{ msg }}</p>
</template>

<script>
  export default {
    props: ['msg']
  }
</script>

We can assert its render output with different props using the propsData option:

import Vue from 'vue'
import MyComponent from './MyComponent.vue'

// A 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')
  })
})

Asserting Asynchronous Updates

Because Vue performs DOM updates asynchronously, assertions on DOM updates resulting from state change will be made in a Vue.nextTick callback:

// this Inspects 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'

  // we wait a "tick" after state change before asserting DOM updates
  Vue.nextTick(() => {
    expect(vm.$el.textContent).toBe('foo')
    done()
  })
})

Check out Vue Test Utils if you need a more in-depth information on unit testing in Vue.