Using Jest with ES6 modules

Today we will focus on a simple implementation of a unit test using Jest in an ES2015 environment.

After some study about the various testing Javascript frameworks out there, I’ve picked up Jest over Jasmine or even Mocha.

Basically for such unit test, you might select any of the most popular frameworks. However using Jest will make you more comfortable once you get your hands on building React applications.

Note that Jest is an OpenSource project from Facebook !

Working with Modules

When it comes to Javascript Standards and more precisely recent ones (if we can tell that 2015 is recent !) such as the ECMA Script Modules (ESM), you might encounter compatibility problems.

Compatibility issues

I’m not just talking about the browsers as usually you already own a decent device to run your favorite up to date Web tools !

Let’s review the various environments you might use while dealing with JavaScript :

  • NodeJs
  • React
  • Angular
  • Other frameworks
  • Browsers (Mozilla, Chrome, Safari, Edge…)
  • Jest !

Babel to the rescue

If you stick to pure JS for rendering within browsers, then using ESM should be working without any worry except that you will need to tell your browser about the type of script it is dealing with.

Or simply add the mjs extension to your script as advised here by Benny Powers. And for more information about the way modules are being loaded, check this page.

I won’t ask you to actually use the extension, the scripts are still JavaScript so introducing a new extension could be confusing according to me and frameworks don’t actually do this.

If you use modules, the most widely known tool to handle such compatibility issues is Babel compiler !

If you follow the Babel documentation, you will see that this tool fits our needs with ECMA Script Modules.

Let’s not discuss much about Babel and rather code !

Coding sample

Here is a very simple module on which we will run a test right after :

function square(num) {
 return num*num; 
} 

export default square;

Save this module under test.mjs (yes I know I’ve used the mjs extension 🙂 – just to avoid the use of type=”module” when loading the script from an HTML page).

Do I need to tell you what the function is doing ?

Node.js & Npm

The JavaScript runtime environment Node allows us to run our JS scripts outside of a browser and thus our unit tests.

Using npm helps us deal with the different libraries necessary to handle the functionalities including the testing framework Jest.

Set up requirements

Using your favorite terminal and assuming you already installed npm on your machine, type the following commands next to your test script.

At first run npm init to initialize your package.json file then :

  1. npm install –save-dev jest
    (we only want Jest for development purposes)
  2. npm install @babel/core @babel/node –save-dev
    (we want babel to help us in a node.js environment)
  3. npm install @babel/preset-env –save-dev
    (using presets you can target a specific environment for compiling)

Configuration

Now prepare a babel relative configuration file .babelrc and add these lines :

{
    "presets": [
        "@babel/preset-env"
    ]
}

Using the above configuration is not recommended by Babel as you don’t precise on which environment your scripts will run.

All ES2015+ will actually be transformed back to ES05.

Finally within jest.config.json file :

{
  "collectCoverage": true,
  "moduleFileExtensions": [
    "js",
    "mjs"
  ],
  "transform": {
    "^.+\\.js$": "babel-jest",
    "^.+\\.mjs$": "babel-jest"
  },

  "testRegex": "((\\.|/*.)(spec))\\.js?$"
}

The later independent files avoids us to flood our package.json.

Here we tell Jest to transform js but also mjs files using Babel and ask Jest to look at tests having spec in the filename only.

The collectCoverage option permits Jest to collect the coverage details while running your tests. You may just skip it, it has no value in this set up.

The Unit test sample

You are reaching the end of this guide, yeah !!

Finally the test sample (test.spec.js) following the naming and spot conventions.

import square from 'test.mjs';

describe('square function', () => {
    it('Compute the square of a number', () => {
        expect(square(2)).toEqual(4);
    });
});

You should be ending your environment with the following code base structure :

.babelrc
jest.config.json
package.json
test.mjs
test.spec.js

Besides these files, you should end up with the package.json.lock with all your local libraries dependencies matching the node_modules folder.

I won’t publish it here as the code should be working independently from the versions you use. I’ll try to keep the examples up to date in case of any major upgrades.

Run the test

Just type in your terminal :

$ npm test

And appreciate the result :

Jest Unit test sample of use
Hest Unit Test example of use

That’s it for this tutorial, I hope you get a better look at Jest for unit testing, we will cover data mocking next.

Stay tuned !

Further reading :

Learn more about ESM alternatives such as CommonJS.

Troubleshooting

You might encounter a few issues if you haven’t followed the configuration files for instance.

-> ReferenceError: regeneratorRuntime is not defined
 
That one is triggered if you are not telling Jest to target your environment, the following lines within .babelrc do the trick :
{
    "presets": [[
        "@babel/preset-env",
        {
            "targets": {
              "node": "current"
            }
          }
    ]]
}
-> SyntaxError: Unexpected token ‘export’
 
Here ESM are not supported, you should be using Babel as explained :).

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Want more information?

Related links will be displayed within articles for you to pick up another good spot to get more details about software development, deployment & monitoring.

Stay tuned by following us on Youtube.

%d bloggers like this: