Open In App

How To Perform Unit Test in NestJS?

Last Updated : 26 Sep, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

NestJS is a Node.js framework for building efficient, reliable and scalable server-side applications. It is built using TypeScript and It offers support for unit testing through the Jest testing framework. In this article, we will learn about performing unit testing in a NestJs.

What is Unit Testing?

Unit testing is a type of software testing where individual components (units) of a software application are tested in isolation. In JavaScript or TypeScript, It could be a single function, method or class. The goal of unit testing is to ensure that each unit of your application works as intended.

In NestJS, a unit might be a service, controller or function within a service. Unit tests are particularly important because they verify the correctness of individual components.

NestJS promotes modular architecture, which is perfect for unit testing because each module can be tested independently. Unit testing in NestJS allows you to ensure that your service classes, controllers and other components function as expected even before integrating them into the complete application.

Setting Up Unit Testing in NestJS

Follow the below steps, to set up the NestJS project.

Step 1: Run the following in the terminal to create a new project.

npx @nestjs/cli new project_name

Step 2: Switch the current working directory to the project folder.

cd project_name

Step 3: Install Testing Dependencies.

By setting up the project, NestJS will by default add required libraries for Jest testing. If still not found use the below command to install.

npm install --save-dev jest @nestjs/testing ts-jest @types/jest

Step 4: Create a Jest configuration file.

If the configuration file doesn't exist then create a new configuration file:

jest.config.js

module.exports = {
moduleFileExtensions: ['js', 'json', 'ts'],
rootDir: 'src',
testRegex: '.*\\.spec\\.ts$',
transform: {
'^.+\\.(t|j)s$': 'ts-jest',
},
collectCoverageFrom: ['**/*.(t|j)s'],
coverageDirectory: '../coverage',
testEnvironment: 'node',
};

Update package.json to include test scripts:

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

Dependencies

"dependencies": {
"@nestjs/common": "^10.0.0",
"@nestjs/core": "^10.0.0",
"@nestjs/platform-express": "^10.0.0",
"reflect-metadata": "^0.2.0",
"rxjs": "^7.8.1"
}

To Run the Test with Jest you can use the following command:

npm test

Key Concepts in Unit Testing

Before we begin, learning example read this key concepts:

  • Unit Test: It is a test that verifies the behavior of a small isolated part of the application (e.g., a service or controller method).
  • Mocking Dependencies: In unit tests, we mock dependencies like services and modules to isolate the component being tested.
  • Test Suite: It is a collection of related tests grouped together using describe(). Like testing login functionality, we can include valid, invalid login, multiple try login cases.
  • Test Case: It is a individual test that is written using it() or test(). Ex, Testing of Valid Login Case.

Example: Unit Testing a Service in NestJS

Before, you begin the example make sure you have completed the Jest setup by following "Setting Up Unit Testing in NestJS" Steps.

Folder Structure

jest-service-structure
Folder Structure

Step 1: Create a cats directory inside src directory, and make the below files.

JavaScript
//src/cats/cats.service.ts

import { Injectable } from '@nestjs/common';

@Injectable()
export class CatsService {
    private readonly cats: string[] = ['Tom', 'Felix'];

    findAll(): string[] {
        return this.cats;
    }

    addCat(cat: string): void {
        this.cats.push(cat);
    }
}

Step 2: Writing a Unit Test For Service:

JavaScript
//src/cats/cats.service.spec.ts

import { Test, TestingModule } from '@nestjs/testing';
import { CatsService } from './cats.service';

describe('CatsService', () => {
    let service: CatsService;

    beforeEach(async () => {
        const module: TestingModule = await Test.createTestingModule({
            providers: [CatsService],
        }).compile();

        service = module.get < CatsService > (CatsService);
    });

    it('should be defined', () => {
        expect(service).toBeDefined();
    });

    it('should return all cats', () => {
        const cats = service.findAll();
        expect(cats).toEqual(['Tom', 'Felix']);
    });

    it('should add a new cat', () => {
        service.addCat('Garfield');
        const cats = service.findAll();
        expect(cats).toContain('Garfield');
    });
});


Output

To run the test, write the following command in your terminal.

npm test
nestjs-test
Perform Unit Test in NestJS

Example: Unit Testing a Controller in NestJS

Before, you begin the example make sure you have completed the Jest setup by following "Setting Up Unit Testing in NestJS" Steps.

Folder Structure

jest-controller-structure
Folder Structure

Step 1: Create a my.service.ts Service.

JavaScript
// src/my-service/my.service.ts

import { Injectable } from '@nestjs/common';

@Injectable()
export class MyService {
    getHello(): string {
        return 'Hello, World!';
    }
}


Step 2: Create a my.controller.ts controller

JavaScript
// src/my-controller/my.controller.ts

import { Controller, Get } from '@nestjs/common';
import { MyService } from './my.service';

@Controller('my')
export class MyController {
    constructor(private readonly myService: MyService) { }

    @Get()
    getHello(): string {
        return this.myService.getHello();
    }
}


Step 3: Write Unit Tests for the Controller

JavaScript
// src/my-controller/my.controller.spec.ts

import { Test, TestingModule } from '@nestjs/testing';
import { MyController } from './my.controller';
import { MyService } from './my.service';

describe('MyController', () => {
    let controller: MyController;

    // Mocking MyService
    const mockMyService = {
        getHello: jest.fn().mockReturnValue('Mocked Hello!'),
    };

    beforeEach(async () => {
        const module: TestingModule = await Test.createTestingModule({
            controllers: [MyController],
            providers: [
                {
                    provide: MyService,
                    useValue: mockMyService,
                },
            ],
        }).compile();

        controller = module.get < MyController > (MyController);
    });

    it('should return "Mocked Hello!"', () => {
        expect(controller.getHello()).toBe('Mocked Hello!');
    });
});


Output

To run the test, write the following command in your terminal.

npm test
jest-controller-output
How To Perform Unit Test in NestJS

Best Practices for Unit Testing in NestJS

You can follow the below best practices when writing Unit Test.

  • Mock External Dependencies: You can avoid real database or API calls in unit tests by mocking dependencies. you can use the docker temporary containers that deletes after test is completed.
  • Write Small, Focused Tests: Each test should cover one specific case or method.
  • Use Test Doubles (Mocks, Stubs, and Spies): Use these to control the behavior of dependencies during tests.
  • Test Error Handling: Ensure that your tests cover both successful and error cases.
  • Keep Tests Fast: Tests should be quick to run which allows you to catch issues early.

Next Article

Similar Reads