How to Perform Unit Testing in NestJS Applications

Updated: December 31, 2023 By: Guest Contributor Post a comment

Introduction

Unit testing is an essential part of developing reliable and maintainable applications. In NestJS, unit tests ensure individual components operate correctly in isolation. This article will guide you through the process of writing and running unit tests within a NestJS application using Jest and Supertest.

Setting Up Your Testing Environment

To start developing unit tests in NestJS, you need to set up the testing environment. NestJS comes with Jest as the default testing framework. Ensure you have the necessary packages installed:

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

Then, update your jest.config.js to accommodate TypeScript by setting the preset to ts-jest:

module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
};

Writing a Basic Unit Test

Start by testing a simple service. Consider a HelperService that has a method add which adds two numbers:

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

@Injectable()
export class HelperService {
    add(a: number, b: number): number {
        return a + b;
    }
}

To test this service, create a test file next to the service file named helper.service.spec.ts:

import { HelperService } from './helper.service';

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

  beforeEach(() => {
      service = new HelperService();
  });

  it('should add two numbers', () => {
    expect(service.add(2, 3)).toBe(5);
  });
});

This test initializes the service and verifies that the add method produces the expected output.

Testing Services with Dependencies

When testing services with dependencies, you can use the Test module from @nestjs/testing to handle dependency injection:

import { Test } from '@nestjs/testing';
import { LoggingService } from './logging.service';
import { HelperService } from './helper.service';

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

  beforeEach(async () => {
    const moduleRef = await Test.createTestingModule({
      providers: [HelperService, LoggingService],
    }).compile();

    service = moduleRef.get(HelperService);
  });

  // Add your tests here
});

This snippet demonstrates how to initialize the NestJS testing module, which takes care of instantiating services with their dependencies.

Advanced: Mocking Dependencies

When a service depends on another component, you should mock the dependency to isolate the tested unit. The following example shows how to mock a dependency in a unit test:

import { Test } from '@nestjs/testing';
import { HelperService } from './helper.service';
import { LoggingService } from './logging.service';

describe('HelperService', () => {
  let service: HelperService;
  let loggingService: LoggingService;

  beforeEach(async () => {
    const moduleRef = await Test.createTestingModule({
      providers: [
        HelperService,
        {
          provide: LoggingService,
          useValue: {
            log: jest.fn(),
          },
        },
      ],
    }).compile();

    service = moduleRef.get(HelperService);
    loggingService = moduleRef.get(LoggingService);
  });

  // Add your tests here using loggingService mock
});

Here, we replaced the actual LoggingService with a mock object, allowing us to verify interactions with it without affecting the real service.

Conclusion

This tutorial has introduced the basics of unit testing in NestJS applications from setting up the environment to testing services with dependencies and mocking. With these tools in hand, you’re now equipped to ensure your components are rock-solid and your application is built on a robust foundation of tested units.