In this article to show how to setup Jest in an Vue.js application. This will guide you through everything in a blank Vue.js template to test components and more
As we’re inside of the Vue.js environment, we’ll also be using <a href="https://alligator.io/vuejs/vue-test-utils-changes/" target="_blank">vue-test-utils</a>
to make it easy when interfacing with native Vue elements.
Setting up our testing environment is easy. In previous versions of the Vue.js CLI, we had to do this manually, but now it comes as standard with the project generation.
Ensure you have the Vue.js CLI installed on your machine by doing the following:
$ npm install -g @vue/cli
# OR
$ yarn global add @vue/cli
# Ensure you have the appropriate version (3.x.x>) with
$ vue --version
Create a new project with the CLI with the following:
$ vue create testing-vue
> Manually select features
> Babel, Linter / Preformatter, Unit Testing
> ESLint (your preference)
> Lint on save
> Jest
> In dedicated config files
$ cd testing-vue
$ code .
$ npm run serve
Now that we’ve generated our Vue project with Jest, we can navigate to the tests/unit
folder. Inside of this folder, we have a file named example.spec.js
:
import { shallowMount } from "@vue/test-utils";
import HelloWorld from "@/components/HelloWorld.vue";
describe("HelloWorld.vue", () => {
it("renders props.msg when passed", () => {
const msg = "new message";
const wrapper = shallowMount(HelloWorld, {
propsData: { msg }
});
expect(wrapper.text()).toMatch(msg);
});
});
As referenced inside of our package.json
, we can run this unit test by typing:
$ npm run test:unit
This gives us the results of all of the unit tests within our project. At the moment, everything passes as expected.
We can add the --watch
flag to this to keep this running in the background as we create and edit new tests.
"scripts": {
"test:unit": "vue-cli-service test:unit --watch"
}
In our small example, we’ll create a new component named FancyHeading
. This will represent a heading that can be customized with a title
and color
using props.
<template>
<h1 :style="headingStyles">{{title}}</h1>
</template>
<script>
export default {
data() {
return {
headingStyles: {
color: this.color
}
};
},
props: ["title", "color"]
};
</script>
In order to unit test this, we’ll need to make a corresponding FancyHeading.spec.js
file within the tests/unit
directory.
A test suite can be thought of as a collection of tests centered around testing a particular module or functionality.
Let’s take a look at our first unit test with Jest and Vue. We’ll investigate it line by line:
import Vue from 'vue';
import FancyHeading from '@/components/FancyHeading.vue';
function mountComponentWithProps (Component, propsData) {
const Constructor = Vue.extend(Component);
const vm = new Constructor({
propsData
}).$mount();
return vm.$el;
}
describe('FancyHeading.vue', () => {
it('should be the correct color', () => {
const headingData = mountComponentWithProps(FancyHeading, { color: 'red' });
const styleData = headingData.style.getPropertyValue('color');
console.log(styleData)
expect(styleData).toEqual('blue');
});
it('should have the correct title', () => {
const headingData = mountComponentWithProps(FancyHeading, { title: 'Hello, Vue!' });
const titleData = headingData.textContent;
expect(titleData).toEqual('Hello, Vue!');
});
});
describe
to encapsulate numerous unit tests surrounding our FancyHeading
component.it
function, firstly providing a description of exactly what we’re testing, followed by a function.It must have the correct color
, we’re mounting our component to a new Vue instance with mountComponentWithProps
.styleData
which contains what we expect to receive from our test.expect
. If we check our terminal with $ npm run test:unit --watch
, we’ll see a PASS
for this unit test.We take a similar approach when testing the title of our heading in the second unit test.
#vue-js #testing