N/A

Have you considered implementing unit testing in your app built on a reactive JavaScript framework? If you haven't explored this yet, I've got you covered. I faced some challenges myself when starting out, but I've put together a helpful guide with code solutions to help you get started with unit testing.

Unit Testing

TL;DR: Want to skip to the code solutions? Just grab the link here: https://github.com/kjugi/meeting-app-unit-tests-playground

Our app to test should contain the following stack: reactive framework, state management and Jest. Let's assume that in our case we are using Vue together with vue-test-utils and Vuex.

While writing unit tests we should ask ourselves one question repeatedly: Can I fake this data?

If you keep this question in mind when writing tests, everything should go smoothly! But of course, there are some common problems that come up during this process, so I will show you how to resolve them.

1. Data mocking is the first and most important rule for unit tests. Without it, tests could be worthless. We can mock almost everything and I highly recommend checking out their documentation — you can find here different kinds of mocks and specific examples when and how to use them.

We should mock API calls and any requests responses by mocking Axios. Then we can mock functions, and expect for some results just to test our case. Here’s a small example:

  

2. Promises and asynchronous code cause a little pain when we need to test an app. Luckily we don’t need to worry about it there because when you are writing new tests you can simply use async/await syntax. In a test it looks like this:

  

3. Timer functions, like setTimeout, can be resolved with one line, using provided by Jest timer mock function, which let us run tests quicker, without waiting for real time to elapse.

A similar approach should be used while working with promises, for example, network requests, they should be resolved as fast as possible, it can be achieved with one simple npm package called flush-promises.

  

4. Complicated, long and unreadable test cases can be fixed by introducing factory functions to our code.

It is a great feature in testing which saves our time and keeps tests short and clean. You can create a local factory function in your test file or go with one global factory function and import it across a whole app when your code is really convenient.

To avoid complicated tests, we should also keep each test case as short as we can. The basic rule to keep is one test case for one method, action or emit.

It’s worth considering grouping lanes with arrange/act/assert pattern.

  • Arrange section sets the necessary information to process the test
  • Act means performing some actions
  • Assert verifies that the results are as expected.

Example for arrange, act and assert pattern:

  

Example for factory function:

  

5. State management is the next station for us. How do we test it? The answer is in distinct files. It is separated from component tests. I suggest testing each type of store element separately or split them by functionality/store modules.

In fact, in components, we should forget about dispatches and commits. You probably guessed that we should mock it and you would be right.

File structure with store modules:

  

Testing mutation, action and getter:

  

6. Date based elements are one of the toughest problems to solve. I mean, you could simply mock Date.now in Jest but if you need to mock some static data in new Date() could be really challenging. Fortunately, you can easily use an npm package for that: jest-date-mock.

This is a basic package which will mock the data provided by us to function and we can revert this data when we finish our test.

  

That’s all for now. I think that these six points are enough to get you started unit testing and inspiring to create some new tests in your app. Let me know in the comments how it goes.

All described issues and more can be found in this demo repository. There’s also a practice directory to challenge yourself in unit tests.

Take care, Filip — Front-end developer at SNOW.DOG