Some tips for writing unit testing Vue Components with Jest

Tram Ho

Using Jest to test Vue.js components can be quite difficult. We need a separate Vue Test Utils package ( @vue/test-utils ) to virtually mount our components and use Jest to run the tests. Because these two libraries work together, it is important to ensure that we do not get confused about which library’s API calls. Along with these libraries, we need to pay attention to the specific methods of JSDOM (virtual browser environment), which comes with Jest. These can be confusing and may prevent us from writing unittest.

For example, shallowMount() is a method of Vue Test Utils to create a shallow wrapper component (using shallow rendering to avoid rendering children components) and beforeEach() is a method of Jest that implements callback arguments before each test. We run shallowMount() inside beforeEach() so that a component is mounted before each test.
I made a list of the common test methods my team used to help write our unit Vue components successfully. Hope this helps others go through the same process.

Initial Setup

Get started by setting up Jest. Install Jest npm package devDependencies

Now, install the Vue Test Utils application and other dependencies like babel-jest , vue-jest , etc. (taken from the Vue Test Utils docs)

Once we have all the packages jest.config.js , let’s create a jest config file named jest.config.js in the root of our project. As an alternative, we can also add the JSON object inside module.exports to the jest: {} attribute to package.json to cut down the number of configuration files we have to manage.

Once we have configured the configuration (mostly collectCoverageFrom source path), we are ready to run Jest!
Now, all we need to do is add scripts: { “test”: “jest” } to package.json. Then run that script.

Writing Test Files

The script above is not very helpful until we have test files that Jest can run, so let’s add a file.
Jest will select * .test.js or * .spec.js in our project directory. I want to put the test files in the same directory as my Vue components and use the component file names.
For example. The component button.vue will have the test button.test.js file in the components/ folder. This helps me manage component files and test files because they are in the same folder and are right next to each other in Explorer in VSCode.

Test File Template

This is a base template test file I use to get started. Note that shallowMount() has different properties like propsData , mocks , stubs , methods , we can set our mount component to mock or stub different component properties.
We call shallowMount() and store the mocked component in a wrapper before testing and destroy the wrapper after each test. That way we are starting with a new state every time we test. This makes the test more predictable.
Jest has test functions like describe() , test() and expect() to set each test and expected value. I wanted to check wrapper.isVueInstance from the beginning to make sure that I assumed the default attribute for the component.

If our component uses Vuex, we need to add Vuex to the Vue instance (here called localVue ) using use() and passing it to shallowMount()

Common Testing Methods

Let’s take a look at some testing methods that cover most types of unit testing.

  • Existence of DOM elements
    We start testing by checking if the wrapper has all the default elements that we expect to be displayed when the component is mounted. We do this by checking actual element tags or other attributes like class, id, etc. Jest’s assertion functions like toBe() along with wrapper.contains() or wrapper.findAll().length from Vue Test Utils Can help with this test.

We can also check the innerHTML of the elements by using the .text () function of the DOM element that wrapper.find () returns.
For example. expect (wrapper.find (‘. blah’). text ()). toBe (‘blah text’).

  • DOM action events
    We can test events that emit when an action is performed in a component. For example. When clicking the close button, the dialog box will be closed by listening to a close event. We use the function trigger() from Vue Test Utils to trigger an event on the selected DOM element and wrapper.emitted() gives a list of emitted events used to check for the existence of the event. desire.

Above we trigger click on closeBtn , we can also trigger events like keydown

  • Accessing Vue wrapper properties
    In case we need to access or change the data , computed , methods and props of our Vue component, we can use the wrapper.vm object because the Vue Test Utils creates an instance of the component in the wrapper . This is useful when we have to mock values ​​for one of the properties.

An exception is that computed properties need to be recalculated using shallowMount() and passed as an attribute. Since we mount our component in beforeEach() and in the test it is necessary to pass the overridden properties in computed

  • Mocking methods and modules
    One of the important things to know when writing unit tests is how to fake or mock module or method implementations that aren’t part of our testing. This helps to make our tests more predictable. We can use the Jest’s fn() and mock() of the Jest margin to return mocked versions. There is also a mocks attribute inside shallowMount() in the Vue Test Utils that is used to mock any global functions our component might be using without having to import the statement.
    Take a look at the mocking functions below:

  • Async callbacks
    If we have asynchronous code in our component, we can use async/await to await async callback, usually Promise.

Demo

Link repo vue-jest-unit-test , I have set up an App component with the tests.

summary

If we handle Jest and Vue Test Utils APIs well, then writing unittest for our Vue Component will be very fast. Writing unittest will help us write better code and be ready to refactor ^^

Link original article

https://medium.com/swlh/tips-on-unit-testing-vue-components-with-jest-e68ff6a28bb5

Share the news now

Source : Viblo