Testing Vue with Jest part — II
This tutorial will not explain you how to configure a vue application. We only will focus on component creation and tests.
So we will use Jest as our test runner installed by default with vue-cli init webpack version 2.9.6+ but if your vue-cli doesn’t has Jest option to install. Feel free to read the part I of this series and install jest on your vue application.
So first of all, what component we will create?
I carefully choose a paginator component, it has a good complexity for create, receive, manipulate and needs to understand data, also can be quite agnostic for all users use in yours applications and manipulate the interface of the component directly without change the backend compatibility with the older paginator.
Well, we need to know the requirements our paginator must have.
So, I think we can doing our first Minimum product viable with:
- Button which will decrease a page
- Button which will increase a page
- The current page number
Ok, lets start!
- Create a folder called awesome-vue-paginator
- Add a vue application in.
- Add Jest to your project.
Now we can start creating our component!!!
OR our first TEST AWWEEE YEAAAH!
Why we will create the test first? For thinking about the component structural design before, forcing we think in the simpliest solution first.
So the cicle of our tests and development will be using Test Driven Development (TDD), if you don’t know what is it please read this!
Ok, lets create our first test file. We will insert into the folder test -> unit -> specs with the filename Paginator.spec.js
Now we can create our first use case in the test file!
As a user
I want to click a button to see the next page
Ok, so we will briefly write a test thinking the next button realy exists.
Ok what we are doing here.
Importing ShallowMount from @vue/test-utils
The shallowMount method will creates a
Wrapper that contains the mounted and rendered Vue component, in this case a Paginator wrapper, and with stubbed child components.
The stubbed components will not be rendered and we can’t access their functionalities. So shallowMount will not render the child components because they are stubbed.
But our first component will not have children. So we can still use the shallowMount method!
Accessing the wrapper API to manipulate the component
The shallowMount receiving Paginator component will return a wrapped paginator which we can be able to access many methods for working with the component.
So now we can find an element on Paginator Component DOM using the find method on our wrapped component.
And we will trigger a behavior on the element that we got it. Triggering the click behavior on our button element.
Getting data from Wrapped Vue Instance
Nice! Now we learn a little about vue test utils!
So we need run the test and see what we get!
Running the tests you will see something like this:
Ouch! Our test are failing :(
So what we need to see the test pass?
- We need create the component on the path: src/components/Paginator with the name Paginator;
- Add a simple template with a button html tag
- Starting currentPage data with 1
- And a on click event in the button wich will sum currentPage + 1
Ok, template created. Now we need run the tests again and see if we resolve our problem.
Ok, but we are forgoten a use case, which we need to start in the first page.
Current page 1 by default
As a user
I want to be at the first page
When I enter on screen
Lets do it our new test!
And now run the test again!
Ok! So now we are ensuring the component starting with currentPage 1 by default.
Previous Button need to back a value
As a user
I want to click a button to see the previous page
I think initialy in this test:
Oh, now we are using a new method from Vue Test Utils. We are setting the currentPage with value 4 on our wrapped paginator with the setData method.
Our test case should decrease a value, if we use currentPage with value default 1, it will be 0. I don’t want it, it will be ensure later with another test case, which we will restrict the previous button click when currentPage is 1. So we set to 4 to expect to the currentPage be 3!
Ok, running the test…
Why the test fail and sum plus 1 resulting 5?
- We don’t create the previous button html tag;
- We don’t differ the previous and next button html.
Ok so we will add this requirements on component template
Running the tests again…
Oh our third test passed but our second fail… It is because our tests now are wrong. The two tests which click the buttons are finding by an button element and not by new refering classes. In the component we put the previous button above the next button.
The find method get the first element. So it will get the previous button, resulting passing the third test but failing the second which need to click on next button.
Refactoring the tests to see passing!
Below we only modified the selectors on paginator.find method to get the right button!
Look it pass!
- We understand a little about the vue test utils using: shallowMount, find, setData, trigger, vm
- We work with TDD, for thinking better about our code and how we will start to develop and test!
- And we covered three user stories with tests increasing quality to our code ❤
In the next story
We will create restrictions to buttons, testing the elements visibility, html attributes and discovering new things about the vue test utils and jest assertions! Lets do it together!!!
See you soon :)