DEV Community

Cover image for Adding Tests for ESM using Jest framework
TD
TD

Posted on • Updated on

Adding Tests for ESM using Jest framework

Writing tests for an application is a crucial process, as it helps make debugging easier and forces us, developers, to write better code.

What is Testing?

In essence, testing is writing code to test that the functionality of your codebase is working and is not breaking in ways unimagined.

Using Jest

Jest is a testing framework for Javascript projects. It ensures that the implemented core functionality of the codebase is not prone to errors by allowing developers to write convenient tests.

Setting up Jest for ESM

The initial step is to install Jest as a dev dependency using npm or yarn

Since I use npm to install node packages, I ran the following command:

npm install --save-dev jest
Enter fullscreen mode Exit fullscreen mode

The next step is to create a jest.config.js file with the following content:

export default { transform: {} }
Enter fullscreen mode Exit fullscreen mode

Finally, we need to modify the test script in package.json.

Typically you would replace the default value of the test with either jest -- or jest. However, since we are using ECMAScript modules in our project, we have to set up the test scriptaccordingly as follows:

"scripts": {
    "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
  },
Enter fullscreen mode Exit fullscreen mode

Writing the first test

Before you write your first test, create a tests or __tests__ directory in the project's root directory.

Here's a sample function that checks if the user is eligible to cast a vote.

// can-vote.js
const canVote = (age) => {
   if(age < 18){
   return false;
   }
  return true;
}
export default canVote;
Enter fullscreen mode Exit fullscreen mode

Here's the test for the above function:

import canVote from '../src/can-vote';

test('should return false if no value for age given', () => {
  expect(canVote()).toBe(false);
});
Enter fullscreen mode Exit fullscreen mode

Let's run the test as follows:

npm test
Enter fullscreen mode Exit fullscreen mode

In the above test, we expect canVote to return false when no argument is passed. This test should fail because we are not dealing with a use case in which the value for age is undefined. As a result, the function returns true with the above implementation. This mistake could go unnoticed when the function definition is more extended and complex.

I encountered a similar bug in the main function of my SSG, because there were no instances where the main function was invoked without passing a value in the codebase.

To fix the problem in the test we wrote, we could modify our canVote function as follows:

// can-vote.js
const canVote = (age = 0) => {
   if(age < 18){
   return false;
   }
  return true;
}
export default canVote;
Enter fullscreen mode Exit fullscreen mode

Now, if we run npm test the test we wrote for canVote should pass, since we are using default parameter value in the function declaration.

Final Thoughts

Writing tests for my project helped me find bugs that would have otherwise gone unnoticed. It's not easy to write tests, but it's a skill I would like to improve. Also, I learned it is challenging to write tests for code you do not understand.

Top comments (3)

Collapse
 
lexlohr profile image
Alex Lohr

Maybe consider vitest as an alternative; it has built-in esm support.

Collapse
 
tdaw profile image
TD • Edited

Thanks for your recommendation; I will give vitest a try. 😊

Collapse
 
rxliuli profile image
rxliuli

I already do this and recommend it too, it's simple to use and also supports the import feature that vite supports, which is handy.