Writing robust Vue.js unit tests using Avoriaz
Writing unit tests is a critical step in building robust, high quality software. When developing Vue.js applications, it is often helpful to write unit tests that make assertions on components and how they are rendered.
In this article we’ll look at writing unit tests for Vue.js applications using Avoriaz, a testing utility library for Vue.js.
For this piece, Vue refers to Vue.js 2.x versions.
Note that a basic understanding of Vue, with the webpack template is required to follow this guide.
Setting Up Our Environment
To get started with our project, we will use the
Vue-cli . This would help us to skip the process of configuring webpack and all other complicated processes.
If you do not have the
Vue-cli installed, we can do so by running the following command:
npm install -g vue-cli
Once we have the
vie-cliinstalled, let’s proceed to creating the application. To do that, we run:
vue init webpack unittest
At this stage, you’ll be prompted with a few questions. You can accept the default option for most of them, the only requirement is that you answer YES to including vue-router and YES to setting up unit tests with Karma and Mocha.
Understanding The Default Test
Next, Let us take a look at our
test\unit\specs\Hello.spec.js . We will notice this block of code:
In the code block above, we will notice:
- The import of Vue library
- The import of our Hello component
- The description of the test, named Hello.vue
- One unit test which says “should render correct content”. Under this test, we mount our component, then declare our
expectfunction, which checks to see that the output is equal to what we are expecting.
Notice that in the test above, we expected that the text content of the
h1 tag under the
hello class would be equal to
welcome to Your Vue.js App
This explains how simple it is for a Vue test to be written. As simple as this method is, there is a simpler method to write tests in Vue.
Writing Vue Tests using Avorias
Remember i mentioned that there is a simpler method for writing unit test in Vue. Here we are. That simple method is using a package called
First, we need to install the package. To do that, let us run the following commands.
// change directory to our folder
// install the avorias package
Now let us re-write the default
hello test using
avoriaz . To do that, let us delete the
test\unit\specs\Hello.spec.js file, then create a new file called
After creating this file, let us replace its content with:
Looking at the above code block, we notice the following differences from the default test spec
- We import mount as opposed to Vue in the default test. This is because avorias comes with a mount helper function, as opposed to extending Vue, then mounting it.
- We used the
text()function rather than using the
textContentproperty. This is because avorias gives us a helper function called
Creating Our Testable Component
Let us create a new file called
Happy.vue in our
src\components folder and paste in the following content:
Let’s have a quick explanation of what we have in the code-block above.
- Our template section comprises one div (root element) which comprise a looped
- We declared our data comprising just one variable called
themwhich is looped in the template section.
- In our mounted call, we called the function called
get_themfunction uses axios to send a GET request to https://restcountries.eu/rest/v2/all. However, we do not use the response. We only use it to fire and async event.
- Finally, we have two computed properties. One which adds a new item to the
themarray and returns it. The second computed property returns a string
Next, we will look at how to test our new component. This means we will test our
get_them function, and our computed properties.
Updating Our Routes
Next, we need to update our routes, so we can have a view of the component we have built so far. To do this, let’s open our
src\router\index.js and replace it with:
In the code block above, we have imported our happy component and added it to our routes.
If we run
npm run dev in our terminal and browse to
http://localhost:8080/#/happy we should see the following image:
Testing Our Components Methods
Now, let us test. If we inspect our method called
get_them , we notice that we had an async call using
axios . Because of this, if we attempt to write tests for our component, we will run into various issues such as:
- Promise is undefined
- Timeout of 2000ms exceeded.
To take care of these issues during testing, we will install two libraries which are:
- Promise: To solve “cannot find variable Promise / Promise is undefined”
- Moxios: This library would stub requests and return fake data into it. So as to fake early completion of our async call.
To install these libraries, we run:
npm install promise moxios
Now we have these libraries installed, let us create a new file called
Happy-avorias.spec.js in our
test\unit\specs\ folder. Let us add the following code into the file:
Let’s understand what we have done on the code block above:
- We imported our mount function as we have explained before
- Next, we imported
Moxiosfor stubbing request.
- We then set a global variable called Promise to the instance of our Promise library. This is so we don't face issues like promise is not defined from Axios.
- We then described our test
- We called two hooks called
afterEachto handle the installation and un-installation of
Moxios. This means
Moxioswill be installed before all tests defined in this file, and will be uninstalled after each test.
- We defined two test criteria
- In the first test criteria, we used Moxios to catch the request going to https://restcountries.eu/rest/v2/all and then return a test data.
- we use
moxios.waitto ensure that the promise is resolved before declaring our expect keyword
- Notice we use
vm.data()to access a data property of our component? This is a helper function provided by
- We check that our data has
happy oneas part of the content in its array, which was assigned to it after the request.
- In the second test criteria, we also used Moxios to stub requests. However, here we found out that the length of our array is equal to 4. which is the length of array we are expecting.
Testing Our Computed Data
Just above, we have seen how to test data, and methods. Here we move into testing computed properties. Testing computed properties with
avorias can be a little tricky as
this isnt bound to computed properties. Refer to the link below about the issue.
When trying to test a computed property using AVA and with Avoriaz, the context of this is not what is expected. I'm…github.com
However, fear not. We will cover how to solve this issue while running our own tests on computed properties.
Let us go back to our
Happy-avorias.spec.js and replace it with the following content:
In the code block above, we will notice the addition of two new test criteria.
- The first criteria says it must return computed data. It checks for the response of our
computed_first()property which does nothing with the
- Note the helper function
computed()by avorias for checking computed properties
- The second criteria says it should have a length of 5. However, the computed property referenced here
thiskeyword which avorias does not bind to computed property
- Notice that instead of expecting
app.computed().all_of_them(), we expected
Explained above is the only difference we need to take into consideration while running computed data. Also, please be informed that the same issue applies to props data.
We can run all our tests by running:
npm run unit
we should get the following results:
Writing unit tests in Vue is as essential as writing your application itself. Most users would not return to an application that has bugs. The easiest way to minimize this bugs to the barest minimum is by writing accurate unit tests.
In this little piece, we have gone through how to write unit tests for Vue using the
The codebase to this little guide can be found here:
Plug: LogRocket, a DVR for web apps
LogRocket is a frontend logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.