UNIT TESTING WITH JEST (with example)
Tags: webdev, javascript, beginners, testing
Published: 2023-01-16 08:30:27

**Unit testing is like when you play a game and you want to make sure all the pieces are working the way they should.**

Imagine you are playing with a toy car and you want to make sure it can drive forward, backward and make turns. You test these things one by one to make sure they work. Similarly, in programming, when we make a program, we also want to make sure all the small parts of the program are working correctly.

 So, we write some special tests that check each part of the program to make sure it's working as expected. It's like playing a game of making sure the toy car works, but instead, we are making sure our program works.


## WHY TESTING IS IMPORTANT 

- helps to ensure that the code is working as expected and that any changes made in the future do not break the existing functionality.

**Unit tests are automated tests that are written to test small, isolated units of code such as functions or methods.** They are typically written by developers and run automatically as part of a continuous integration pipeline.

In this article, we will be using **Jest** as our test framework to demonstrate how to write unit tests for a Node.js and TypeScript application. 

Jest is a popular test framework that is widely used in the JavaScript community and has built-in support for TypeScript.

Here is an example of a test suite for a class Utils which has two static methods, parseUrl and toUpperCase.

**create a nodejs project, install everything on this package.json devDependencies to replicate**

`e.g- npm i -save-dev @types/jest jest ts-node ...`



```json
{
  "name": "TestCourse",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "jest"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@types/jest": "^29.2.5",
    "@types/node": "^18.11.18",
    "jest": "^29.3.1",
    "ts-jest": "^29.0.5",
    "ts-node": "^10.9.1",
    "typescript": "^4.9.4"
  }
}
```


OUR PROJECT STRUCTURE:

```
.
├──...
├──src
|  ├──app
|  |    ├── Utils.ts
|  └── test
|        ├── Utils.tsUtils.test.ts
├── jest.config.js
├── package-lock.json
├── package.json
└── ...  
```

**REMEMBER TO HAVE THIS ON THE jest.config file:**

```javascript
module.exports = {
  // tells Jest to look for test files in the src directory
  roots: ["<rootDir>/src"],
  // tells Jest to use the ts-jest transformer for TypeScript files
  transform: {
    "^.+\\.tsx?$": "ts-jest",
  },
  // tells Jest which files to consider as test files
  testRegex: "(/__test__/.*|(\\.|/)(test|spec))\\.[jt]sx?$",
  // tells Jest which file extensions to look for when resolving imports
  moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"],
  // prints the test results in a more detailed format
  verbose: true,
};
```

The jest.config.js file is a configuration file for Jest. 

It tells Jest where to look for files to test, how to transform TypeScript files, and which files to consider as test files.


**Utils.ts:**

```javascript

import { UrlWithParsedQuery,parse } from "url";

export class Utils{
    // This is the parseUrl method that will parse the url and return an object with the url properties
    public static parseUrl(url:string):UrlWithParsedQuery{
        return parse(url, true)
    }

    // This is the toUpperCase method that will convert the arg to uppercase
    public static toUpperCase(arg:string){
        return arg.toUpperCase()
    }
}

```


The class is composed of two methods, **one for parsing the url and returning an object with the url properties and the other for converting a string to uppercase.** 


**Unit.test.ts**

```javascript
import { Utils } from "../app/Utils"

describe('Utils test suite', () => {
    // first test case for the toUpperCase method
     test('first test', () =>  {
        const result = Utils.toUpperCase('abc');
        // asserts that the result is equal to 'ABC'
         expect(result).toBe('ABC') })
        
    // test case for parseUrl method with simple url
    test('parse simple URL', ()=>{
        const parsedUrl = Utils.parseUrl('http://localhost:8080/login');
        // asserts that the href, port, protocol and query properties are as expected
        expect(parsedUrl.href).toBe('http://localhost:8080/login');
        expect(parsedUrl.port).toBe('8080')
        expect(parsedUrl.protocol).toBe('http:')
        expect(parsedUrl.query).toEqual({})
    })

    // test case for parseUrl method with url with query 
    test('parse URL with query', ()=>{
        const parsedUrl = Utils.parseUrl('http://localhost:8080/login?user=user&password=pass');
        const expectedQuery ={
            user:'user',
            password:'pass'
        }
        // asserts that the query property is as expected
        expect(parsedUrl.query).toEqual(expectedQuery);
    })
})
```

The above code is an example of a test suite for a class Utils which has two static methods, **parseUrl and toUpperCase.**



The test suite uses the** describe function** from Jest to **group together the tests for this class.**

 Each test case uses the test function to define an individual test and the expect function to make an assertion about the expected outcome of the test.

**The toBe matcher is used to check that the result of the function is equal to the expected value, while the toEqual matcher is used to check that the object is equal to the expected object.**

toBe: on strings and numbers 

toEqual: on objects

**RUN THE TEST**

run `npm test` to run the test 

make sure that is sspecified on your package.json as we have above

results:

![clara_situma_testing_with_jest](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/16ilhp8sq7j939fttmia.png)