Criando testes no Nestjs

Marcos Ramos
edifyeducation
Published in
5 min readMay 26, 2022
Nestjs — Uma ótima opção para desenvolvimento de aplicações em node.js e typescript.

Ao falarmos de frameworks javascript, o que logo vem em mente são os frameworks de frontend (React, Angular, Vue). Porém no backend, também existem frameworks que realizam um trabalho muito competente. Entre eles, o NestJS é uma solução que tem se destacado, com bastante recursos disponíveis (modularização, segurança, cacheamento, filas, suporte a microserviços e muito mais). Nesse post, falarei um pouco sobre testes automatizados na abordagem do framework em questão.

A princípio, quando o assunto são testes, a proposta do framework é promover boas práticas no desenvolvimento, proporcionar uma forma eficiente de criar os testes, promover integrações com frameworks de teste e fazer mocks (simulações) de componentes das aplicações.

💡 É importante destacar que o Nest não impõe a utilização de nenhuma ferramenta de teste específica. Você pode utilizar qualquer ferramenta de teste juntamente com o framework, bastando para isso substituir os elementos necessários.

Por padrão, o Nest tem integração com a suite de testes Jest, que possui uma série de recursos que permitem executar testes integrados e testar uma aplicação das mais diversas formas possíveis.

O Nest utiliza por padrão a integração com o Jest, mas permite utilizar qualquer outro framework de testes.

O Nest facilita a criação dos testes automatizados através de sua CLI. Ao criar uma classe, ele cria automaticamente os arquivos de teste. Isso faz com que o foco se mantenha na elaboração do teste e de menos configurações.

Testes unitários

Os testes unitários possuem a finalidade de testar uma única parte da aplicação. Eles são desenvolvidos dentro dos arquivos que possuem o sufixo .spec.ts . Ao executar os testes, por padrão o Nest escaneia a pasta src da aplicação e procura por arquivos com esse sufixo.

Arquivo de teste unitário no Nestjs

Testes ponta-a-ponta

Os testes ponta-a-ponta têm o objetivo de testar as interações entre as classes de uma aplicação e serviços externos. Esse tipo de teste tenta simular o máximo possível o seu cenário de uso real. A partir do crescimento de uma aplicação, torna-se cada vez mais difícil e demorado testar todas as suas funcionalidades individualmente. Os testes ponta-a-ponta auxiliam na manutenção do seu comportamento adequado e ajudam a garantir seus requisitos. Os arquivos de teste ponta-a-ponta ficam dentro da pasta test e possuem com o sufixo .e2e-spec.ts

Arquivo de testes integrados no Nestjs

Criando os testes

Agora que já sabemos quais são os tipos de arquivos que devemos lidar, vamos abri-los e verificar como os testes são desenvolvidos:

import { Test, TestingModule } from '@nestjs/testing';
import { CoursesService } from './courses.service';
describe('CoursesService', () => {
let service: CoursesService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [CoursesService],
}).compile();
service = module.get<CoursesService>(CoursesService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

describe - descreve a sua finalidade, no primeiro parâmetro e no segundo passa uma função anônima. Todo o teste se encontra dentro deste método.

beforeEach - utiliza a classe Test e o método createTestingModule para definir os providers do nosso módulo de testes. E por fim utiliza compile para rodar tudo e instancia o provider em service .

it - É neste ponto que fica a lógica do teste. É onde você define o que será testado e qual o resultado esperado. Para chegar neste objetivo, foram utilizados os hooks expect e toBeDefined.

Vamos criar mais um teste dentro da classe para demonstrar o desenvolvimento de testes unitários:

import { Test, TestingModule } from '@nestjs/testing';
import { CoursesService } from './courses.service';
describe('CoursesService', () => {
let service: CoursesService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [CoursesService],
}).compile();
service = module.get<CoursesService>(CoursesService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});

//novo teste
it('should return one course', () => {
expect(service.findOne(1).name).toBe('Curso de Typescript');
})
});

Nesse novo teste criado, estamos utilizando o método findOne de CoursesService para retornar o nome do curso 1. E espera-se que esse nome seja ‘Curso de Typescript’. Observe que a maneira de desenvolver os testes é intuitiva: você informa o que se espera ser executado através do teste, utilizando expect e o que deverá ser retornado utilizando toBe . Ao desenvolver testes com o Jest, utilizaremos muito desta semântica e ele conta com uma quantidade enorme de métodos para auxiliar no desenvolvimento.

Apenas para fins de exemplo, foi criado o service CoursesService .

import { Injectable } from '@nestjs/common';
import { Course } from './entities/course.entity';
@Injectable()
export class CoursesService {
private courses: Course[] = [
{
id: 1,
name: 'Curso de Typescript',
description: 'Curso de Typescript',
tags: ['node.js', 'nestjs', 'typescript']
},
{
id: 2,
name: 'Curso de Javascript',
description: 'Javascript do iniciante ao avançado',
tags: ['javascript', 'ecm', 'node']
},
];
findAll() {
return this.courses;
}
findOne(id: number) {
return this.courses.find(course => course.id === Number(id));
}
create(createCourseDto: any) {
this.courses.push(createCourseDto);
}
update(id: string, updateCourseDto: any) {
const indexCourse = this.courses.findIndex(
course => course.id === Number(id));
this.courses[indexCourse] = updateCourseDto;
}
remove(id: string) {
const indexCourse = this.courses.findIndex(
course => course.id === Number(id));
if (indexCourse >= 0) this.courses.splice(indexCourse, 1);
}
}

Observe que CoursesService possui um array contendo alguns cursos (para fins de exemplo) e também o método findOne. Eles foram utilizados no teste.

Executando os testes

Agora que já temos o teste feito, devemos executá-lo. E para isso utilizaremos o terminal para executar o comando npm:

npm test -- courses.service 
Execução de testes através da integração do NestJs com o framework de testes Jest

A imagem demonstra a execução de 1 arquivo de teste contendo 2 testes. Um desses dois testes já vem criado por padrão pelo Nest. O outro é o teste que criamos. Ambos passaram com sucesso.

Com isso, nós concluímos nosso exemplo de testes unitários. Lembrando que foi apenas um pequeno grão de areia em um universo enorme que este tema nos proporciona. Em breve, nos aprofundaremos em mais tópicos sobre testes.

Links úteis:

Documentation | NestJS — A progressive Node.js framework

--

--