How to Use Jest for JavaScript Unit Testing

, ,

Jest is a JavaScript testing framework maintained by Meta. It works with Bable, TypeScript, Node.js, React, and more. In this case, we’re going to set up Jest and test a JavaScript function.

How to Install & Set Up Jest

You can refer to the step-by-step instructions via the official Getting Started documentation, but our simple setup is as follows:

  1. Open VS Code and create the following files:
    1. example.js – the function you’ll test will be here
    2. example.test.js – will include our tests for the example.js function
  2. In VS Code, click View in the toolbar and open Terminal.
  3. Type npm init to generate a package.json for the Jest test runner.
  4. Type npm i --save-dev jest to save this package as a development environment and install Jest (just return through all the prompts).
  5. Open your package.json, which should look like this:
{
  "name": "jest-testing",
  "version": "1.0.0",
  "description": "",
  "main": "exampe.test.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "jest": "^29.0.3"
  }
}
  1. Change line 7 to "test": "jest" and save.

How to Run Jest Tests In Terminal

After you’ve written test, to run these tests, you can type npm test into Terminal. Optionally, you can configure your scripts to automatically watch and run tests each time you save a file in your development testing environment. To do this:

  1. Open package.json
  2. Add "watch": "jest --watch *.js" to the scripts to watch all files. Your file should now look like this:
{
  "name": "jest-testing",
  "version": "1.0.0",
  "description": "",
  "main": "exampe.test.js",
  "scripts": {
    "test": "jest",
    "watch": "jest --watch *.js"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "jest": "^29.0.3"
  }
}
  1. Type npm run watch into Terminal.

How to Write Jest Test

Let’s look at an example of how to run tests using Jest. First, we need something to test, so let’s open our example.js file and write a function that takes two parameters a and b and returns their remainder.

const remainder = (a, b) => a % b;
module.exports = remainder;

It’s important to export your function, so you can include it in your example.test.js file later.

We’ll write our tests in the file named example.test.js and we’ll test these three scenarios:

  1. Test case 1: 3 / 2 equals a remainder of 1.
  2. Test case 2: 1000.5 / 500.5 equals a remainder of 1.
  3. Test that 4 / 2 equals a remainder of 1. (Intentionally wrong)

Before we start writing our unit tests, we need to include the remainder function at the top of our example.test.js file:

const remainder = require('./example.js');

Jest Test Syntax

The syntax of a test function is as follows:

test('The description of our test.', () => {
    expect(functionName(pram1, pram2)).toBe(expectedResult);
});
  • We have the test( ) function
  • We give the test a helpful description inside quotes followed by a comma
  • Then we have an anonymous function () => { }
  • inside the anon function, we have the expect() and toBe() functions.
  • Inside the expect() function, we can pass the function that we want to test and provide it with any parameters that the function requires. In the above example, we’re passing a function and providing it with two parameters to test e.g. functionName(pram1, pram2)
  • Then we can use the toBe() function to tell the test what the result should be.

He’s a reminder of the remainder function that we’re testing:

const remainder = (a, b) => a % b;

Example Jest Test 1: 3 / 2 = 1

test('Test 1: remainder of 3 / 2 equals 1', () => {
    expect(remainder(3, 2)).toBe(1);
});

In our test above, we’ve explained what our test is testing by giving it a description of:

'Test 1: remainder of 3 / 2 equals 1'

This name can be anything we want. It’s up to us to provide an accurate name for each test.

Next, we called our remainder function, providing it with two numbers to test, 3 and 2, and telling it that we expect the result to be 1.

expect(remainder(3, 2)).toBe(1);

We know that the answer is 1, and this test should pass. Once we save our example.test.js file, in VS Code terminal, we will see our test results:

In VS Code Terminal, we can see:

  • The test passed for our file example.test.js.
  • A green check mark for our test ‘Test 1: remainder of 3 / 2 equals 1’
  • Beside Tests: we see that 1 passed out of 1 total test.

Let’s write our second test.

Example Jest Test 2: 1000.5 / 500.5 = 1

test('Test 2: Remainder of 1000.5 / 500.5 to equal 1', () => {
    expect(remainder(1000.5, 500.5)).toBe(500);
});

Above, we’re testing the function remainder() with 1000.5 / 500.5 and expect the remainder to be 500.

When we save, we’ll see in Terminal that both test passed since we see their names with check marks:

✓ Test 1: remainder of 3 / 2 equals 1
✓ Test 2: Remainder of 1000.5 / 500.5 to equal 1

We also see that 2 out of 2 tests passed

Tests:       2 passed, 2 total

Example Jest Test 3: 4 / 2 = 1

In this example, we’re going to make our test intentionally fail, so we can see what a failure test in Jest’s results looks like. We know that the remainder of 4 divided by 2 is 0, but let’s tell our test that we expect the result to be 1.

test('Test 2: remainder of 4 / 2 to equal 1 (this should fail since the reminder if 0 )', () => {
    expect(remainder(4, 2)).toBe(1);
});

Save and look at our super helpful test results:

From the top down, we can see that our test failed since not all tests in our test suite passed. Jest lets us know that two tests passed and one failed:

 FAIL  ./example.test.js
  ✓ Test 1: remainder of 3 / 2 equals 1
  ✓ Test 2: Remainder of 1000.5 / 500.5 to equal 1
  ✕ remainder of 4 / 2 to equal 1 (this should fail since the reminder if 0 ) (2 ms)

On the next couple of lines it clearly highlights which test failed and where it lives in your example.test.js file:

 ● remainder of 4 / 2 to equal 1 (this should fail since the reminder if 0 )

    expect(received).toBe(expected) // Object.is equality

    Expected: 1
    Received: 0

      12 |
      13 | test('remainder of 4 / 2 to equal 1 (this should fail since the reminder if 0 )', () => {
    > 14 |     expect(remainder(4, 2)).toBe(1);
         |                             ^
      15 | });

      at Object.toBe (example.test.js:14:29)

Next, we see that our test suite failed because 1 out of our 3 tests failed:

Test Suites: 1 failed, 1 total
Tests:       1 failed, 2 passed, 3 total

We now know why the test failed and how to fix it on line 14 of our example.test.js file. So let’s go fix the expected result to be 0 to make sure our tests pass.

Now our tests have passed!

Extra reading:


Leave a Reply

Your email address will not be published. Required fields are marked *