What IS Jest, And How Is It Related To A Vue 3 Project?

I was recently talking with a developer who said "TDD Ruins Weekend" and then proceeded on to "TDD ruins lives". The hyperbole was amusing, but seeing as how I was contracted to help teach TDD to that team it was pretty concerning. After patiently working my way through to understand the issues, it wasn't really TDD that the developer disliked, it was the lack of understanding of the tools involved with testing Vue apps. I have to agree there, because Vue is so new and so cutting edge there aren't yet as lot of resources on the web (especially for Vue 3). To help that situation, I promised the series of blog posts I have been sharing over the last few weeks and we're getting near the end of that series. This one, explaining about Jest, is meant to help disambiguate which tools do what when testing a Vue 3 app.

So, back to our original question: "What IS Jest, ad how is it related to a Vue 3 project"? The answer is actually pretty simple, if a bit long winded. Jest provides us 4 main things when used in a Vue project:

  • Jest is our test runner - It actually is the process which executes our tests
  • Jest provides mocking capabilities - It allows us to mock aspects of our code to test in isolation
  • Jest is our assertion framework - It provides us with methods like expect and others to make assertions
  • Jest is our code coverage calculator - It can track what code is exercised by our tests and calculate file, line, and branch coverage

Jest Is A Test Runner

Like other testing tools (Mocha, Chai, JUnit, Cucumber, etc...), Jest provides us a framework within which we can execute tests. Unlike some other frameworks, Jest is intended to be VERY easy to set up and get running. In fact, Jest is billed and requiring ZERO configuration . . . which in the case of a complex Vue app is not really true. Jest is also extensible so that it can support a wide variety of different libraries, toolkits, and frameworks (Like Vue).

In most cases, Jest is simply executed from the command-line and it will locate your test files and execute them. In the case of Vue we need a little more support. First, we need to install the Jest plugin for Vue: vue-jest. This plugin gives Jest the ability to understand and process Vue files. We also need to tell Jest what types of files to look for because by default it's looking for the most common style of tests (e.g. .test.js). In our case, we have been using jest-cucumber and so we have to modify the default behavior of Jest. Finally, we need to tell Jest how we would like to resolve modules in our project. In a Vue 3 project that requires another small config change. Let's look at a Jest config for use with Vue and jest-cucumber below:

Let's walk through what we see in this file. First, when you have created a Vue 3 project using the Vue CLI tool, one of the prompts you get is asking if you want "dedicated config files", and when you use this option you get individual files in the root of the project to configure most aspects of your application. Jest is no different and you get a file called jest.config.js. These settings combine to help Jest know how to execute you tests in the proper environment. Code Coverage, module name mapping (allowing us to use short names in "import" statements), transformers (which transpile from ES6/7/Typescript/CoffeeScript/etc...), serializers (which allow us to take snapshots of the current state of the DOM), and others are all configured here. Once the configuration is set, you can just execute jest from within your project's root directory and it can handle the rest.

Jest Provides Mocking

Mocking can be an important tool to help us isolate classes/functions/components from each other when running unit tests so that we limit the scope of our tests. For example, you probably don't want to make actual REST requests during a unit test, so you might MOCK a library like Axios. The main workhorse for mocking in Jest is the jest.fn method which creates a mock function which we can make assertions about. Back to our example of Axios, we might create a mock of the Axios get method as shown below:

We see that we have created a function on the axios object called get. That function is "mocked" to provide a pre-set response so that we know what to expect in our tests and therefore can make assertions. We also have made some assertions in the mocked function about what parameters/data is being passed to the mock function. In a later step of the test, we can make asserts about when, how, and how many times this mock function was called by using Jest's expect method.

Jest is capable of mocking more things.

Jest Is Our Assertion Framework

Any tests which are run from Jest will be injected with a function called expect. The expect function allows us to make all sorts of assertions about what is happening inside of our tests, and any failed assertions will cause our test to fail. As shown above, we have made assertions about mock functions, but we can also make assertions about DOM elements, variable state, CSS styles applied, and much more.

There are a lot more things you can assert with Jest's expect method, but the examples above should give you a good start.

Jest Is Our Code Coverage Calculator

Last, but certainly not least, when Jest is running our tests we can ask it to calculate code coverage for us. We saw in the configuration file shared above that we can enable code coverage in our Jest configuration, but we can also use Jest command-line arguments to achieve the same results. Coverage can even be configure to require certain levels of coverage and when those thresholds are not met we can fail the build.

Summary

Jest is a pretty nice alternative to other solutions like Mocha or Chai. It's also relatively easy to set up and run. The main difficultly (as is true in a lot of the JavaScript ecosystem) is know which tools provide which functionality. Hopefully now you have a good understanding of what Jest provides and can do for us.

Comments

Popular Posts