This website uses cookies to enhance the user experience

Testing (Unit, Integration, E2E)

Share:

Testing is a crucial aspect of application development that ensures the system behaves as expected. It checks whether the designed logic is working correctly and helps in identifying any bugs or discrepancies. In this tutorial, we will explore different types of testing such as Unit, Integration, and End to End (E2E) testing in the framework of Nest.js.

Nest.js is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript and is built with TypeScript. By the end of this chapter, you will learn how to write different types of tests for your Nest.js application.

Let's dig deeper.

Unit Testing

Unit tests ensure that individual components of the application work as expected. In a Nest.js application, these components could be classes, services, or controllers.

Let's assume we have a MoviesService that provides a get movie method which retrieves a specified movie's details. Let's write a test to ensure it works correctly.

import { Test, TestingModule } from '@nestjs/testing';
import { MoviesService } from './movies.service';

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

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

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

  it('should return a movie', async () => {
    const result = await service.getMovie('Inception');
    expect(result).toBeDefined();
    expect(result.title).toEqual('Inception');
  });
});

We first create a MoviesService instance using the Nest.js testing module (TestingModule). The getMovie method is then tested with a predefined output.

Integration Testing

Integration tests check how individual components of the application work together. For instance, consider a scenario where a MoviesController is making use of MoviesService to fetch a single movie's details.

Let's see how we could write an integration test for this scenario.

import { Test, TestingModule } from '@nestjs/testing';
import { MoviesController } from './movies.controller';
import { MoviesService } from './movies.service';

describe('MoviesController', () => {
  let moviesController: MoviesController;
  let moviesService: MoviesService;

  beforeEach(async () => {
    const app: TestingModule = await Test.createTestingModule({
      controllers: [MoviesController],
      providers: [MoviesService],
    }).compile();

    moviesService = app.get<MoviesService>(MoviesService);
    moviesController = app.get<MoviesController>(MoviesController);
  });

  describe('getMovie', () => {
    it('should return a single movie', async () => {
      const result = { title: 'Inception' };
      jest.spyOn(moviesService, 'getMovie').mockImplementation(() => result);

      expect(await moviesController.getMovie('Inception')).toBe(result);
    });
  });
});

In the integration test above, we create instances of both MoviesController and MoviesService. Then, using Jest's spyOn function, we mock the getMovie method of the MoviesService. We then test the getMovie method of the MoviesController to make sure it's working as expected with the MoviesService.

End-to-end (E2E) Testing

End to end testing is performed to verify the flow of an application from start to finish. The purpose of carrying out E2E tests is to identify system dependencies and to ensure that the corroborative behavior of all components is as expected.

import { Test, TestingModule } from '@nestjs/testing';
import * as request from 'supertest';
import { AppModule } from './../src/app.module';

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

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

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

  it('GET /movies', () => {
    return request(app.getHttpServer())
      .get('/movies')
      .expect(200)
      .expect([{ title: 'Inception', director: 'Christopher Nolan' }])
  });
});

In the example above, a GET request is made to /movies and we're expecting it to return a 200 status code along with an array containing movie objects.

Conclusion

This tutorial introduced different types of testing in a Nest.js application like unit, integration and end-to-end (E2E) testing. These testing methods ensure the smooth functioning of your application. Keep in mind that although writing tests can be time-consuming, they significantly reduce the time you'd spend later in debugging and troubleshooting issues. Don't underestimate the power of a well-tested application!

0 Comment


Sign up or Log in to leave a comment


Recent job openings