Using Vue Test Utils with Jest to test Vue.js under Webpacker in Rails

icelandcheng
Jun 14 · 6 min read

When it comes to testing for Ruby on Rails project, RSpec must be the most common tool that people would implement. By using RSpec, we could easily write a good testing script for our Rails project and test our project thoroughly. But after Rails 6 integrates Webpacker in the project as default, there are more chances that we would implement Javascript frameworks in the Rails project, and RSpec might no longer enough for us to test our Rails project thoroughly including testing those Javascript functions, so is that a good way for us to test those Javascript functions and scripts under Webpacker in a Rails project? one of the answers is using Vue Test Utils with Jest. In the following section, I’ll show how to set up and test Vue.js under Webpacker in Rails project by using Vue Test Utils with Jest.

Package Installation

Before start testing, there are some packages that need to be installed in our project.

Install Vue Test Utils and vue-jest to process vue single file components.

yarn add @vue/test-utils
yarn add vue-jest --dev

Installing babel-core, because we are going to use babel and import vue single file components .vue extension inside our tests.

yarn add babel-core@bridge --dev

Setting Config

After all the packages are installed, some settings need to be added to package.json before start testing.

Adding the scripts to package.json, and you could run your tests through yarn test

"scripts": {
"test": "jest"
}

You could define the location of your tests. To do this you could add roots to package.json You also need to tell Jest to transform .vue files using vue-jest and transform .js files with babel-jest, and to do so the moduleFileExtensions and transform params need to set as below. The test environment also need to be clarified, so testEnvironment params need to set in package.json The example config setting is as below.

"jest": {
"roots": [
"app/javascript/spec"
],
"moduleFileExtensions": [
"js",
"json",
// tell Jest to handle `*.vue` files
"vue"
],
"transform": {
// process `*.js` files with `babel-jest`
"^.+\\.js$": "babel-jest",
"^.+\\.vue$": "vue-jest"
},
"testEnvironment": "jsdom"
}

Writing Test

First of all, Creating a test file under the testing root(app/javascript/spec), and the file name should end with .test.js

For example, creating a Home.test.js (the script is as below). At first, I just want to try if all the settings are done and the .test.js could run, so I only addconsole.log('Done!') in the testing script. Then, run yarn test

test('the very first test', () => {
console.log('Done!')
})

After running yarn test , If the test file could run and all the tests are pass, the results in the console might show as below picture. It would show a green pass.

But if some tests failed, you might see some red fail in the result as below picture.

The code style of Vue Test Utils is similar to RSpec. You could also use describe function to add more description of what you are testing. For example, we could add describe function outside the test function to describe more about the test.

describe('Just try if it works', () => {
test('the very first test', () => {
console.log('Done')
})
})

Run yarn test and the result in the console will show the description we put in the describe function.

After checking the test files could run, we could test some vue components in our Rails project. In the test file, Vue Test Utils should be imported first, and we also need to import the vue component we want to test. The example code is as below.

import { mount, shallowMount } from '@vue/test-utils'
import Home from '../src/components/XXX.vue'

When import Vue Test Utils, mountor shallowMount should be imported. They both could be used to wrap vue components and render them when testing. These two method work similarly. The only difference is shallowMount doesn’t render child components so that it allows us to test the component in isolation to make sure that child components are not included in the test. Vue Test Utils provides many methods for us to test vue components, for example, it provides a find method to find an element in components and it also provides a html method to check if the component html is as expected.

For example, there is a AuthPanel.test.jsto test the AuthPanel component AuthPanel.vuein my example project. For more information, the AuthPanel component is a component that I use on the login page in this project

We could see In AuthPanel.test.jsas below, the Vue Test Utils and AuthPanel.vue are imported. In this case, I want to test if the component is rendered as expected, so I use shallowMount to wrap the component AuthPanel.vue and render it, then using html method to check if the component is rendered as expected or not.

import { shallowMount } from '@vue/test-utils'
import AuthPanel from '../src/components/AuthPanel.vue'
describe('AuthPanel.vue', () => {
test('check html', () => {
const wrapper = shallowMount(AuthPanel);
expect(wrapper.html()).toBe(
`<div class="auth-panel">
<br>
<input type="email" name="email" id="email">
<br>
<input type="password" name="password" id="password">
<button type="button" class="btn btn-secondary">Sign Up</button>
</div>`)
})
})

After running yarn test if the test passes and shows a green pass in the console, it means that the component renders just as we expect.

But if the test fails, the result in the console will show what is different from what we expect as below picture, and we could follow the instruction to modify our code.

After reading the example above, we have a basic idea about how to start testing Vue.js under Webpacker in a Rails project. I only share using the html method to test vue component, but actually, there are more useful methods that Vue Test Utils provides for us to implement in testing, so I’ll share more articles about this related topic in the future. The source code I provide in the examples in this article could be found in the below repo of my Github page. If you are interested in the detail of settings and scripts, feel free to reach the below link. Thank you for your watching!

Reference

Nerd For Tech

From Confusion to Clarification

Nerd For Tech

NFT is an Educational Media House. Our mission is to bring the invaluable knowledge and experiences of experts from all over the world to the novice. To know more about us, visit https://www.nerdfortech.org/.

icelandcheng

Written by

Programming Skill learner and Sharer | Ruby on Rails 💎 Vue.js 🌐Web Map API

Nerd For Tech

NFT is an Educational Media House. Our mission is to bring the invaluable knowledge and experiences of experts from all over the world to the novice. To know more about us, visit https://www.nerdfortech.org/.