I’ve been gathering some examples from my past work with Vue.js when testing applications and realized I could create an article that could help my colleagues and (hopefully) you.

Vue.js is a very popular open-source javascript framework to build user interfaces and single page applications, easy to understand and with a lot of companies starting to adopt.

To test Vue.js applications, I’m using Vue Test Utils as the javascript testing utility. It has a lot of good methods to help you mount your components and test the cases you need to test. Like unit test your component functions or test interactions.

The reason for this article is that to test some parts of the application you will always do the same thing. You have a way to test functions, to mock requests, to mock function returns, etc.

So, why not create a pocket guide for later use?

Let’s start?

Component State

One thing that you need to be careful is mutating the state. In Vue, if you don’t declare the state properties you will not be able to mutate them because they are not reactive!

Be sure to initiate with all the properties you need and don’t do something like this because it will not work:

beforeEach(() => {

state = {};

} it('should do someting', () => {

state.foo = 'bar';

});

You need to:

beforeEach(() => {

state = {

foo: 'hello',

}

} it('should do someting', () => {

state.foo = 'bar';

});

Note that I’m using the beforeEach method to reset the state before each test.

Component mount

The first thing to do is to mount the component. To do this, we’re going to use Vue Test Utils to help us out.

The shallowMount is the first method we’re going to use. This method allows you to mount the component and will be rendered with stubbed child components.

Like this, you don’t need to worry about using or mounting them as well. This method will mount and render everything for you.

Vue instance

To create a Vue class wrapper without polluting the global Vue class when adding components, mixins, props, etc, we’re going to use as well a method from Vue test utils, the createLocalVue method.

import Vue from 'vue';

import { shallowMount, createLocalVue } from '@vue/test-utils'; const localVue = createLocalVue(); describe('caption.vue', () => {

let wrapper; beforeEach(() => {

wrapper = shallowMount(ComponentName, {

localVue,

propsData: {},

});

});

});

Mocking functions

To mock functions, we’re going to get the help of Jest and a special method fn where it returns a mock function and where you have access to some useful methods. I will show you more below!

To mock a method from your Vue instance, you can have access using the vm variable of your Vue class.

wrapper.vm.didBlur = jest.fn();

Mock return values of functions

If you need to mock the return value of a method from a module, you’ll need to require the whole module, even if you’ve used named exports.

const captionsHelper = require('@/js/helpers/captions');

captionsHelper.didClickOutside.mockReturnValueOnce(false);

Expect n function calls

If you are expecting some function to be called n times, be careful if you are calling the function in another it statement.

To expect n function calls:

expect(wrapper.vm.didBlur.mock.calls.length).toBe(1);

Expect if an event was emitted

Event emitted through component

You need to call the function that will emit the event

Check if the event was emitted

Check what arguments has been passed

describe('#didBlur', () => {

it('should emit setActiveCaptionState event', () => {

wrapper.vm.didBlur();



expect(wrapper.emitted('setActiveCaptionState')).toBeTruthy();

expect(wrapper.emitted('setActiveCaptionState')).toEqual([

[{ caption: wrapper.vm.subtitle, isActive: false }],

]);

});

});

Event through global $eventHub

Create a stub function with jest

Add the stub as the callback of the event

Call method that will emit the event

Check if the event was emitted or the arguments passed

it('emit handleCaptionClicked event', () => {

const stub = jest.fn();

wrapper.vm.$eventHub.$on('handleCaptionClicked', stub);

wrapper.vm.handleClick(); expect(stub).toBeCalled();

expect(stub).toBeCalledWith(wrapper.vm.subtitle.start_time);

});

Check if the method in the component was called

Call method that will emit the event

Check if the event was emitted or the arguments passed

it('emit changeLineBackgroundWarning event', () => {

wrapper.vm.changeLineBackgroundWarning = jest.fn();

wrapper.vm.handleInput(event);



expect(wrapper.vm.changeLineBackgroundWarning).toHaveBeenCalled();

});

Test watchers

Set the props or state that you’re watching

Change the props or state that you’re watching

Expectation

it('should change the state prop isRead to true', () => {

wrapper = shallowMount(Caption, {

localVue,

propsData: {

subtitle: {

start_time: 0.5,

},

currentTime: 0,

},

});



wrapper.setData({ isRead: false });

wrapper.setProps({

currentTime: 1,

}); expect(wrapper.vm.isRead).toBeTruthy();

});

Test Vuex independently

Don’t forget that you need to import the real mutation/action/getter that you want to test because you’ll call it later.

Testing Actions

You should call the action from the store

Commit, dispatch, etc, should be jest functions so you can check if they were called or not

If you want to check if an action dispatches other actions or commit any mutation, you can do:

// Check if a specific action has been called

it('should initiate the smartcheck plugin', () => {

state.showSmartcheck = true;

actions.setTaskState(

{ dispatch, commit, getters, state },

{ taskFromServer: task, localStorageTaskType: 'captioning' },

); expect(dispatch).toHaveBeenCalledWith('initSmartcheckPlugin');

});

Testing Getters

For getters, the only thing you’ll need is to check if the getter is returning what you’re expecting. It can be in a different data structure like an object or different data based on your current state.

describe('taskInfo', () => {

const state = {

id: 'cenas',

type: 'cenas',

status: 'cenas',

}; it('should return the right properties', () => {

expect(getters.taskInfo(state)).toEqual({

id: state.id,

type: state.type,

});

});

});

Testing Mutations

To test mutations, the only thing that you need to test is if the state has been changed. To do that, we:

Create a state object

Pass the state as mutation’s arguments

Check if the state is what you expect

import mutations from '@/js/store/modules/foo/mutations'; beforeEach(() => {

state = {

foo: 'bar'

};

}); it('should change foo state to john', () => {

mutations.CHANGE_TO_JOHN(state);

expect(state).toEqual({

foo: 'john',

});

});

And that’s it for now!

I’ll probably update the article with more cases. This will my pocket guide for future references!