DEV Community

Cover image for Testes de integração com Nestjs, Jest, Supertest, Prisma e Testcontainers
davi_arttur
davi_arttur

Posted on • Updated on

Testes de integração com Nestjs, Jest, Supertest, Prisma e Testcontainers

Motivação

Bem, não tenho muito costume em fazer esses tipos de publicação, mas como não achei nada especifico com a stack que utilizo no meu dia a dia, então resolvi trazer esse step by step.

Nossa API

Para esse cenário de teste, resolvi criar uma API Rest utilizando o Nestjs juntamente com o Prisma para realizar a persistência dos dados no DB.

Setup para realizar os testes

Certifique-se de ter o Docker e Node rodando na sua máquina


import { INestApplication } from '@nestjs/common';
import { Test } from '@nestjs/testing';
import { PrismaClient } from '@prisma/client';
import {
  PostgreSqlContainer,
  StartedPostgreSqlContainer,
} from '@testcontainers/postgresql';
import { execSync } from 'child_process';
import { AppModule } from 'src/app.module';
import * as request from 'supertest';

describe('test POST /users', () => {
  let prisma: PrismaClient;
  let app: INestApplication;
  let container: StartedPostgreSqlContainer;

 beforeAll(async () => {
    // iniciando o container docker
    container = await new PostgreSqlContainer().start();

    // configurando a URL de conexão do prisma
    const urlConnection = `postgresql://${container.getUsername()}:${container.getPassword()}@${container.getHost()}:${container.getPort()}/${container.getDatabase()}?schema=public`;

    // definir a URL de conexão para conexãp do prisma
    process.env.DATABASE_URL = urlConnection;

    // criar as tabelas definidas no prisma no banco de dados
    execSync('npx prisma db push', {
      env: {
        ...process.env,
        DATABASE_URL: urlConnection,
      },
    });

    // importar o modúlo que queremos testar
    const moduleRef = await Test.createTestingModule({
      imports: [AppModule],
    }).compile();

    // criar a aplicação
    app = moduleRef.createNestApplication();

    // Instanciar o prisma client com a URL de conexão
    prisma = new PrismaClient({
      datasources: {
        db: {
          url: urlConnection,
        },
      },
    });

    // Iniciar a aplicação
    await app.init();
  });
Enter fullscreen mode Exit fullscreen mode

Feito isso já temos nosso setup pronto para iniciar os testes. A biblioteca @testcontainers/postgresql vai abstrair toda parte de inicialização do banco de dados.

Casos de teste

  it('deve criar um novo usuário', async () => {
    // Act
    const response = await request(await app.getHttpServer())
      .post('/users')
      .send({
        email: 'test@mail.com',
        name: 'John Doe',
      });

    // Assert
    const userDb = await prisma.users.findFirst();
    expect(response.statusCode).toBe(201);
    expect(userDb.email).toBe('test@mail.com');
    expect(userDb.name).toBe('John Doe');
  });

  it('deve lançar um erro porque já existe um usuário com esse email', async () => {
    // Act
    const response = await request(await app.getHttpServer())
      .post('/users')
      .send({
        email: 'test@mail.com',
        name: 'John Doe',
      });

    // Assert
    expect(response.statusCode).toBe(422);
  });

  it('deve lançar um erro porque não foram enviados os dados para criação do usuário', async () => {
    // Act
    const response = await request(await app.getHttpServer()).post('/users');

    // Assert
    expect(response.statusCode).toBe(400);
  });
Enter fullscreen mode Exit fullscreen mode

Depois de executarmos todos os testes...

  afterAll(async () => {
    // encerrar o container em execução
    await container.stop();
  });
Enter fullscreen mode Exit fullscreen mode

Executar os testes

npm run test
Enter fullscreen mode Exit fullscreen mode

Nosso terminal

Image description

Containers no docker

Image description

Links

Documentação do testcontainers para o Node: https://node.testcontainers.org/modules/postgresql/

Meu repositório no github:
https://github.com/daviArttur/nestjs-testcontainers

Top comments (1)

Collapse
 
andersoncampolina profile image
Anderson Campolina

Excelente Davi. Os comentários foram bem colocados e ajudou muito a entender o processo todo. Faz mas esse tipo de post pra gente!