Jest - Getting Started



In this chapter, we'll introduce you to the basics of Jest to help you get started with testing, whether you're working with small functions or large applications. By the end of this chapter, you'll be able to:

  • Write your first test with Jest.
  • Use basic assertions to verify your code.
  • Organize and structure your tests effectively.

Jest - First Test

In this section, we will guide you step-by-step through writing and running your first Jest test.

Set Up Your Project

Before writing tests, make sure Jest is installed in your project. If you haven't installed Jest yet, check the installation steps in the previous chapter.

Create a Simple Function to Test

First, let's create a simple function that adds two numbers. We will test this function with Jest. Create a file called sum.js and write the following code:

// sum.js
function sum(a, b) {
  return a + b;
}

module.exports = sum;

Write a Test for the Function

Next, we'll write a test for the sum function.

  • In your project, create a __tests__ folder if it doesn't exist.
  • Inside the __tests__ folder, create a file called sum.test.js.
  • In sum.test.js, write the following test code:
// sum.test.js
const sum = require('../sum');

test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3);
});

Explanation of the test:

  • test(): is a Jest function used to define the test case.
  • expect(): is used to check the result of the function.
  • .toBe(): is a Jest matcher that checks if the result is equal to the expected value.

Run the Test

Now that you've written your test, let's run it. Open your terminal and type:

npm test

Jest will run your test and show the result in the terminal:

Understand the Output

After running the test, you'll see something like this if the test passes:

> jest

PASS  __tests__/sum.test.js
   adds 1 + 2 to equal 3 (3 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        0.557 s, estimated 3 s

Handling Test Failures

If there's an error in your code, Jest will show a failure message. For example, if the sum function is wrong, modify it like this:

// sum.js (incorrect version)
function sum(a, b) {
    return a - b; // Wrong operation
}

module.exports = sum;

Then run npm test again. You will see this in the terminal:

> jest

FAIL  __tests__/sum.test.js
 adds 1 + 2 to equal 3 (4 ms)

Test Suites: 1 failed, 1 total
Tests:       0 passed, 1 failed, 1 total

Fix the Error

To fix the test, correct the sumfunction:

// sum.js (correct version)
function sum(a, b) {
  return a + b; // Correct operation
}

module.exports = sum;

Run npm test again, and the test should pass this time.

Jest - Basic Assertions

In Jest, assertions are used to check if the values in your tests meet the expected conditions. Below, we will cover the most commonly used assertions in Jest and provide examples of how to use them.

Using toBe() for Exact Equality

The toBe() matcher checks if a value is exactly equal to another value, which works well for primitive types like numbers or strings.

test('subtract five minus three equals two', () => {
    expect(5 - 3).toBe(2); // Passes because 5 - 3 equals 2
});

Here, toBe(2) checks if the result of 5 - 3 equals 2. The test passes if the value is correct.

Using toEqual() for Deep Equality

The toEqual() matcher checks if two objects or arrays are deeply equal. It's useful for comparing objects or arrays that may have nested values.

test('object assignment with new values', () => {
    const data = { fruit: 'apple' };
    data['color'] = 'red';
    expect(data).toEqual({ fruit: 'apple', color: 'red' });
});

In this test, toEqual() checks if the data object is equal to { fruit: 'apple', color: 'red' }. The test passes when the objects have the same values.

Using toBeTruthy() and toBeFalsy()

  • toBeTruthy() checks if a value is truthy (i.e., a value that evaluates to true in JavaScript).
  • toBeFalsy() checks if a value is falsy (i.e., a value that evaluates to false in JavaScript).
test('truthy test with a non-zero number', () => {
    expect(10).toBeTruthy(); // Passes because 10 is truthy
});

test('falsy test with an empty string', () => {
    expect('').toBeFalsy(); // Passes because an empty string is falsy
});

In these tests, 10 is truthy, and an empty string '' is falsy, so both tests pass.

Using toBeNull()

The toBeNull() matcher is used to check if a value is exactly null. This is useful when you want to confirm that a variable is explicitly set to null.

test('checks if value is null', () => {
    const value = null;
    expect(value).toBeNull(); // Passes because the value is null
});

The test will pass because the value is null.

Using toBeDefined()

The toBeDefined() matcher is used to check if a value is not undefined. It's useful when you want to confirm that a variable has been assigned a value (i.e., it is defined).

test('checks if value is defined', () => {
    const value = 'Hello';
    expect(value).toBeDefined(); // Passes because the value is defined
});

This test passes because the value has been assigned 'Hello'.

Using toBeUndefined()

The toBeUndefined() matcher checks if a value is undefined. This is useful when you want to confirm that a variable has not been assigned a value yet.

test('checks if value is undefined', () => {
    let value;
    expect(value).toBeUndefined(); // Passes because the value is undefined
});

The test passes because the value is not assigned and is implicitly undefined.

Jest - Test Structure

In this section, we'll explain how to structure your Jest tests and organize them in a way that makes your code easier to maintain and understand.

Test Structure Overview

Jest tests follow a simple structure, which includes three main parts:

  • Describe Block: Groups related tests together.
  • Test Cases: Defines individual test scenarios.
  • Assertions: Checks if the output matches the expected result.

Grouping Tests with Describe Block

The describe() block is used to group related tests under a common label. This makes it easier to organize your tests by feature or functionality.

// Purpose: Group related tests together
describe('Calculator Functionality', () => {
    // Related tests for addition and subtraction go here
});

You can also nest describe() blocks for more complex test structures.

Writing Test Cases with test()

The test() function is used to define each individual test. In this function, you describe what you are testing and what the expected result should be.

describe('Simple Math', () => {
    test('adds 2 and 3 correctly', () => {
        expect(2 + 3).toBe(5); // Adds 2 and 3, expects 5
    });

    test('subtracts 5 from 10 correctly', () => {
        expect(10 - 5).toBe(5); // Subtracts 5 from 10, expects 5
    });
});

You can group multiple test cases inside a describe() block for better organization.

Verifying Outputs with Assertions

Assertions are used to check if the result of a test matches the expected value. Jest provides several matchers to perform different checks.

  • toBeGreaterThan(): Checks if a number is greater than the specified value.
  • toBeLessThan(): Checks if a number is less than the specified value.
describe('Basic Assertions', () => {
    test('checks if 10 is greater than 5', () => {
        expect(10).toBeGreaterThan(5); // Passes because 10 > 5
    });

    test('checks if 2 is less than 5', () => {
        expect(2).toBeLessThan(5); // Passes because 2 < 5
    });
});

Complete Example

Let's implement a simple calculator with addition and subtraction and write tests for it.

Create the Calculator Function

Create a file calculator.js and write the following code:

// Calculator Functions
function add(a, b) {
    return a + b;
}

function subtract(a, b) {
    return a - b;
}

module.exports = { add, subtract };

Write Tests for the Calculator

Next, create a test suite for the add() and subtract() function in calculator.test.js.

const { add, subtract } = require('./calculator');

describe('Calculator Functionality', () => {
    // Tests for addition
    describe('Addition', () => {
        test('adds 2 and 3 correctly', () => {
            expect(add(2, 3)).toBe(5);
        });

        test('adds negative numbers correctly', () => {
            expect(add(-2, -3)).toBe(-5);
        });

        test('adds a positive and a negative number correctly', () => {
            expect(add(10, -5)).toBe(5);
        });
    });

    // Tests for subtraction
    describe('Subtraction', () => {
        test('subtracts 5 from 10 correctly', () => {
            expect(subtract(10, 5)).toBe(5);
        });

        test('handles negative results', () => {
            expect(subtract(5, 10)).toBe(-5);
        });

        test('subtracts a negative number correctly', () => {
            expect(subtract(10, -5)).toBe(15);
        });
    });
});

The add() function adds two numbers, and the subtract() function subtracts one number from another. The tests check if both functions work correctly with positive and negative numbers.

Advertisements