본문 바로가기
Web/JavaScript

[Jest] JavaScript Code Unit Testing

by llHoYall 2020. 10. 1.

Jest is introduced on the homepage as "Jest is a delightful JavaScript Testing Framework with a focus on simplicity".

In other words, Jest is used for testing JavaScript.

As far as I know, Jest is based on Jasmine, so it is similar to Jasmine.

Now, let's learn the fundamental of Jest.

Installation

Install Jest in your project folder.

$ yarn add -D jest
  or
$ npm i -D jest

Configuration

Now, add scripts for Jest in the package.json file.

"scripts": {
  "test": "jest",
  "test:watch": "jest --watch",
  "test:cov": "jest --coverage"
},

Usage

$ yarn test

This command tests your code only once.

$ yarn test:watch

This command watches code changes and tests code whenever changes occur.

$ yarn test:cov

This command tests your code only once and gets the test coverage as well.

Example

Now, let's test with some examples.

The folder structure is as below.

+- src
|  +- calculator.js
|  +- calculator.spec.js
+- package.json

Create a code to test

I made a simple calculator module.

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

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

function multiply(a, b) {
  return a * b;
}

function divide(a, b) {
  return a / b;
}

module.exports = {
  add,
  subtract,
  multiply,
  divide,
};

It is so simple. haha

Create a unittest

The name of unittest file conventionally follows as below.

<Module name to test>.test.js
  or
<Module name to test>.spec.js

You can also use ts as well if you config for TypeScript.

const calc = require("./calculator");

describe("Test Calculator Module", () => {
  it("adds 1 and 2 to equal 3", () => {
    expect(calc.add(1, 2)).toEqual(3);
  });

  it("subtracts 2 and 1 to equal 1", () => {
    expect(calc.subtract(2, 1)).toEqual(1);
  });

  it("multiplies 2 and 3 to equal 6", () => {
    expect(calc.multiply(2, 3)).toEqual(6);
  });

  it("divides 4 and 2 to equal 2", () => {
    expect(calc.divide(4, 2)).toEqual(2);
  });
});

First, import a module to test.

describe represents the test suite. In other words, a test group that combines similar tests.

It can be nested.

it represents an individual test. In other words, it is a single meaningful test.

 

This is the result with coverage.

Yay~ We nailed it!!

Setup and Teardown

You can use setup and teardown like other test frameworks.

describe("Description of Test Suites", () => {
  beforeEach(() => {
    // Preparation before each tests
  });

  afterEach(() => {
    // Cleanup after each tests
  });

  // Tests
});

beforeEach is called each time before every test in order to prepare.

afterEach is called each time after every test in order to clean up.

Asynchronous Code

You can also test asynchronous code with callback, promise, and async/await.

Let's create async.js.

function asyncAdd(a, b, callback) {
  setTimeout(() => {
    callback(a + b);
  }, 1000);
}

function asyncSubtract(a, b) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (b === 0) {
        reject(new Error("Error"));
      }
      resolve(a - b);
    }, 1000);
  });
}

function asyncMultiply(a, b) {
  return new Promise((resolve) => setTimeout(resolve(a * b), 1000));
}

module.exports = { asyncAdd, asyncSubtract, asyncMultiply };

I made an asynchronous version of the calculator.

And then, create an async.spec.js file.

const asyncModule = require("./async");

describe("Test Asynchronous Module", () => {
  it("tests callback", (done) => {
    asyncModule.asyncAdd(1, 2, (result) => {
      expect(result).toBe(3);
      done();
    });
  });

  it("tests promise (resolve)", (done) => {
    asyncModule.asyncSubtract(2, 1).then((result) => {
      expect(result).toBe(1);
      done();
    });
  });

  it("tests promise (reject)", (done) => {
    asyncModule
      .asyncSubtract(2, 0)
      .then((result) => {
        expect(result).toBe(2);
        done();
      })
      .catch((e) => {
        expect(e).toBeInstanceOf(Error);
        done();
      });
  });

  it("tests async/await", async () => {
    const result = await asyncModule.asyncMultiply(2, 3);
    expect(result).toBe(6);
  });
});

Jest wait until the done callback is called before finishing the test.

Using this, we can test the asynchronous code with callback, promise, and async/await method.

Next

Now, you can test code with Jest.

Jest is the most popular testing framework recently.

Therefore, most frameworks such as CRA, Nest, etc., have a Jest configuration built-in.

You just write the test code and test!!

 

Take a look expect methods list, and try to use it.

There are lots of methods.

 

Now, go and enjoy Jest!!!

댓글