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.