When talking about Jest, people usually associate it with React, this is due to the fact that Facebook has spent a lot of time ensuring Jest was a good fit for React, but it’s far from being just a test framework for React applications.In fact Jest can work well with any library or framework that uses (or can be compiled down to) JavaScript.
In this series I’ll take a library and show the process I used to get Jest configured and ready to work with it.I hope that it will help be people more comfortable using Jest with other frameworks.
I’ll start with Vue.js because it will allow me to show different configuration options and because it has a server side renderer that is a nice candidate for snapshot tests.
Although there are already existing integrations for Vue, I’ll pretend none exist and I’ll to go through the process of trying to set up a new framework from scratch.
I believe this way will be much more useful as people might have similar issues when trying to set up their own framework.
Let’s start!We’ll use
vuejs-templates/webpack_webpack - A full-featured Webpack + vue-loader setup with hot reload, linting, testing & css extraction._github.com
to create our first Vue application.
npm install -g vue-clivue init webpack vue-jest
We get asked some questions, we’ll say yes to bootstrap the proposed unit tests that uses karma and mocha, this way we can use the community conventions for unit tests.Since Jest is not an e2e test framework we can skip the NightWatch part.
The first step now is to add Jest, to do this we’ll just type
yarn add -D jest
Note: Although I use Yarn in this tutorial, you can use npm. I use yarn because I have most of those dependencies locally cached, making the experience much faster for me.
Now we’ll change the test script in the package.json to run Jest
This way we can just run
yarn test
to start Jest; that’s exactly what we’ll going to do next:
As expected Jest is not working out of the box, the error hints that a module cannot be found, by looking at the test in question we can see that there’s an
statement, but that the path that is pointing to is not actually under the specs folder and so it cannot be found.
Jest provides a module mapper option, that allows us to fix this.
If we look at the project’s webpack configuration, we can see this:
based on that we can add a jest/moduleNameMapper configuration to the package.json root:
After saving and re-running Jest we’ll now be presented with a new error:
If we look at the src/components/Hello.vue file is pretty clear what’s going on here: our JS is trying to require an HTML file, and that of course doesn’t work out of the box.
What we need to do to make this work, is instruct Jest to preprocess the file to return a JS object that will work for both us and Vue.
Jest offers a transform option that can map multiple regular expression patterns to different processors, so let’s add one for .vue files:
We need to create a jest/jest-vue.js file that will handle the transformation:
Passing Jest the — no-cache option (transforms get cached otherwise) will now move us the next error which is very similar to the previous one:
This is because the import statement is not recognized by node, all we need to fix this is adding a second transform that will process the file using babel-jest:
Ok. time to run again:
Good, this error is because the expectation is not in the Jest format. Fixing this is as easy as changing
notice the .to.equal here…
to
…and the .toBe here.
In this case it was quite easy as there is only a single expectation, but if you are going to migrate an existing test suite you might want to look at https://www.npmjs.com/package/jest-codemods to bulk process all of your files.
Let’s run again and:
Yay! We got Jest configured and ready to rumble, let’s now make a Jest snapshot, shall we?
To do this I’ll use the vue-server-renderer, let’s run:
yarn add -D vue-server-renderer
And add a snapshot test:
It works, but let’s take a look of our snapshot:
it works, but…
everything is on a single line… I think we can do better, can’t we?
When implementing snapshots I’ve always wanted it to be extensible and that’s why the pretty-printer we are using has a plugin system. Jest also very conveniently has a snapshotSerializers configuration option that we’ll use here, but before that we need to install an html “prettifier”:
yarn add -D js-beautify
We can now add the snapshot serializer configuration to the jest section in the package.json:
and create this jest/htmlSnapshotBeautifier.js:
Jest’s snapshot serializers must be objects with a test and a print function: test instructs the plugin to be activated or not for a given a node, while print returns the prettified value.
Now, after running yarn test again, we get:
Jest remembers the previous snapshot and is telling us that the result has changed, looks good so let’s save this new one by passing the -u flag and then we can check the resulting file again:
This is much better!
This ends the first post in this series, I hope people will find it useful to understand how easy is to use Jest with libraries other than React and that they get inspired to start using Jest in their projects.