Vuex + IDD: Part2

Frontend with route navigation (still with fake backend)

Alberto Gualis
Coding Stones
5 min readMay 23, 2017

--

This is the second article on a series about unidirectional data flow architecture based on Vuex and IDD.

In the previous post we created a very simple Vue page and got focused on testing vuex actions and mutations.

In this post we’ll add some components to the existing page, we’ll test their UI (checking DOM changes) and we will see how easy is to integrate the router into Vuex.

We slowly keep on building our example demo. You can check the code in the following repo:

Before adding a real backend we want to show you how to create and test components that use Vuex store.

Adding new components

If you remember, we had just one component in our first example. Now it’s time to add new components and split responsibilities. For example, we had the following code to show the loading state while the server was loading the sessions:

Now, we’ve created a new component (Spinner.vue), so the code above have been replaced by this one:

In the future, it could be interesting to pass the loading state as a prop from the parent components, but let’s keep things simple. Remember that we had a centralized store, so the spinner component can access that store by himself to be notified each time the loading state changes:

We use the ‘loading’ getter to automatically render state changes in the component

This new spinner component is totally independent and could be used inside any component of our app, so we decided to register it globally by adding this line in App.vue:

Testing DOM changes in components

We would like to automatically test that the new component shows a spinner when ‘loading’ is true in the Vuex store, but until now, we just had unit tests where we were not interested in the template of the component. Now it’s time to test changes in the DOM. For that, we use these three tools:

avoriaz, mocha-webpack and jsdom

Avoriaz

Avoriaz is a testing utility library that provides a wrapper that helps creating and manipulating Vue components in our tests (is analogous to Enzyme if you come from the React ecosystem).

Let’s see how to use Avoriaz to test our simple Spinner component:

Dom test of our simple Spinner.vue component

Mocha-webpack

The tests shown in our previous post where very fast and simple because they were independent of Vue. We didn’t need to precompile the .vue files, so webpack was not necessary in that context. Now it’s different, we need to exercise a component to check changes in it’s UI (DOM).

The official solutions involve using the karma test runner, but we always look for faster tests to achieve faster feedback.

Mocha-Webpack is a test runner that precompiles your test files (including .vue ones) automatically with webpack, before executing tests with mocha.

jsdom

jsdom is a JavaScript based headless browser that we use, again, to increase the speed of our tests. We just need to create a .setup.js file and pass it to mocha-webpack, so we’ll override global properties like ‘window’, ‘navigator’ or ‘document’.

Running “DOM” tests

Remember that we’ll have tests that will be independent (unit tests) and tests that will need to take care of Vue and the DOM (aka DOM tests). We want to distinguish between the two kind of tests and be able to run them separately:

DOM tests (run with npm run avoriaz):

We added this line to package.json:

As you can see, we are using the existing webpack config file (webpack.base.conf.js) to preprocess our vue components and we are requiring ‘.setup.js’ file to config jsdom.

Our “dom” test files will have the following syntax:

We know this naming it’s coupled with the avoriaz tool, which could be replaced in the future, but we decided to make it explicit to have a clear separation between types of tests.

Unit tests: (run with npm run unit):

We needed to update the old unit script to avoid unit tests trying to parse *.avoriaz.js files:

And we mantain the old format for the unit tests:

Sync vue-router and Vuex

We introduced a new page component (Session.vue) that will be used to create sessions with a form (you’ll see it in the next post):

WIP component to create sessions

We need a new route for this new component.

In the last version we just had the home page so we did not need to navigate between routes. Now we have added this button:

Button to trigger route navigation

With this HTML:

When we click that button the router will navigate from “/” home route to the “new-session” route and we would like to control that route change from the Vuex store. That’s very easy to achieve in two steps:

  • Sync router and state in App.vue:

After that, we will have a new object (route) showing the router state in our Vuex store:

You can check your sync route using vue devtools

Extra ball: Showing a modal

We finally wanted to show how easy is to integrate Vue with some of its plugins. We will use sweet-modal to illustrate it.

We decided to open a modal when there’s an error in the connection with the backend. In our previous example we used this markup to show those kind of errors:

We replaced that with a new component which, like the spinner, controls it’s own UI by watching the centralized store:

Our new component opens a modal each time an error is detected (by watching Vuex error getter):

New Component that opens modal when an error happens

In future posts

We’ve come a long way, but our application is still quiet useless.

In the next post we’ll add a validated form to create sessions and we’ll see how to test the interactions with the router.

Now it’s your turn to play with our github repo and give us some feedback.

See you soon!

At the Coding Stones we help companies developing software and we also provide training and mentoring. If you liked this post and you want more, contact us, maybe we can play together with your band.

--

--