Unit Testing and E2E Testing in NestJS with Jest

Unit Testing and E2E Testing in NestJS with Jest

Learn about Unit Testing and End-to-End (E2E) Testing in NestJS using Jest. This comprehensive guide covers how to set up Jest, write unit and E2E tests, and prepare for NestJS-related interview questions. Improve your NestJS testing skills with practical examples and best practices.

Imagine you built a toy and you want to make sure it works perfectly before giving it to your friend. You would check if the toy works as expected, right? Maybe you press a button, turn a knob, or shake it to make sure it’s functioning correctly.

In software development, we do something similar to ensure our code works properly. This is called testing. Testing is like checking to see if your code (the toy) behaves the way it’s supposed to.

There are two main types of testing that we often do in NestJS: Unit Testing and End-to-End (E2E) Testing. In this blog, we will use Jest, a JavaScript testing framework, to help us with both types of testing.


What is Unit Testing?

Unit testing is like checking if each small part of your toy works correctly by itself. In the world of software, these small parts are called “units.” A unit could be a function, a method, or even a class. In unit testing, we test one unit at a time to see if it does what it’s supposed to do.

For example, if you write a function that adds two numbers, unit testing will check if this function returns the correct result every time you give it two numbers.

In NestJS, you use unit tests to check individual components or services in your application.


What is E2E Testing?

E2E (End-to-End) testing is like testing the entire toy after it’s assembled to make sure everything works together as expected. Instead of checking just one button or one part, you test how all the parts interact with each other.

In software, E2E testing checks whether different parts of your application work together correctly. For example, you might test if a user can log in, submit a form, and receive a response from the server.


How to Set Up Jest in NestJS

Before we dive into writing tests, let’s first set up Jest in a NestJS project.

1. Install Jest in NestJS

If you haven’t already set up Jest in your NestJS project, here’s how you can do it:

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

2. Configure Jest

In your package.json, configure Jest with the following settings:

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

This configuration tells Jest to use TypeScript, look for files that end with .spec.ts, and put the test results in a coverage folder.


Writing Unit Tests in NestJS with Jest

Now that we have Jest set up, let’s write a simple unit test.

Example: Unit Testing a Service

Suppose we have a service in our NestJS application that adds two numbers:

// add.service.ts
import { Injectable } from '@nestjs/common';

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

Now, let’s write a unit test to check if this service adds numbers correctly:

// add.service.spec.ts
import { Test, TestingModule } from '@nestjs/testing';
import { AddService } from './add.service';

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

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

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

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

Here’s what’s happening in the test:

  • beforeEach: This sets up the test environment before each test. It creates an instance of AddService.
  • it(‘should add two numbers correctly’): This is the actual test. It checks if add(1, 2) returns 3.

Writing E2E Tests in NestJS with Jest

End-to-End (E2E) tests check the behavior of your entire application. Let’s say you want to test if a user can log in and fetch data.

Example: E2E Testing with Supertest

First, we’ll install supertest, a library to make HTTP requests for E2E testing:

npm install --save-dev supertest

Let’s write an E2E test for a login endpoint:

// auth.e2e-spec.ts
import * as request from 'supertest';
import { Test } from '@nestjs/testing';
import { AppModule } from '../src/app.module';

describe('AuthController (e2e)', () => {
let app;

beforeAll(async () => {
const moduleFixture = await Test.createTestingModule({
imports: [AppModule],
}).compile();

app = moduleFixture.createNestApplication();
await app.init();
});

it('/auth/login (POST) should return 200 and a token', () => {
return request(app.getHttpServer())
.post('/auth/login')
.send({ username: 'test', password: 'test' })
.expect(200)
.expect((res) => {
expect(res.body.token).toBeDefined();
});
});

afterAll(async () => {
await app.close();
});
});

Here’s what’s happening in the E2E test:

  • beforeAll: This sets up the application before the tests run.
  • it(‘/auth/login (POST) should return 200 and a token’): This test sends a POST request to /auth/login with a username and password, then checks if the response contains a token and the status is 200 (success).
  • afterAll: This cleans up and closes the application after the tests.

Interview Questions and Answers

Q1: What is the difference between Unit Testing and E2E Testing in NestJS?

A1:

  • Unit Testing focuses on testing individual units (like services or functions) in isolation to ensure they work as expected.
  • E2E Testing, on the other hand, tests how different parts of the application work together as a whole, like simulating user actions and checking the entire flow of requests and responses.

Q2: How do you mock dependencies in Unit Tests in NestJS?

A2: In NestJS, you can use jest.mock() or jest.spyOn() to mock dependencies. For example, if a service relies on another service, you can mock that service to avoid calling real external APIs or databases.

jest.mock('external-service'); // Mocks the external service

Q3: What is the role of beforeEach and afterAll in Jest?

A3:

  • beforeEach is used to set up the testing environment before each test case runs.
  • afterAll is used to clean up after all the tests have run, such as closing connections or stopping servers.

Q4: How do you test asynchronous code in Jest?

A4: Jest allows you to test asynchronous code by using async/await, done() callback, or returning a promise.

it('should fetch data', async () => {
const data = await service.fetchData();
expect(data).toBeDefined();
});

Companies Asking About Unit Testing and E2E Testing in NestJS

Here are a few companies that have asked about unit testing and E2E testing in their NestJS-related interviews:

  1. Globant – They focus on full-stack development and might ask about testing your NestJS backend services.
  2. Turing – Frequently asks about unit testing and how you would handle real-world scenarios in microservices.
  3. Accenture – They might ask you to demonstrate your understanding of NestJS testing, especially in relation to a RESTful API.

Conclusion

Unit Testing and E2E Testing are important to ensure your NestJS application behaves as expected. Unit tests focus on individual units of your code, while E2E tests check if the entire system works together. By using Jest, you can automate these tests and catch errors before they reach production.

Testing might seem challenging at first, but once you get the hang of it, you will have more confidence in the stability and reliability of your applications.

Interested in learning more about Microservices and NestJS? Check out our latest blogs for more in-depth guides, tutorials, and best practices on building scalable applications with NestJS and microservices.

Leave a Reply

Your email address will not be published. Required fields are marked *