Pular para o conteúdo principal

Testes de integração do microservice em Node

No vídeo abaixo, segue a demonstração de como funciona os testes de integração para o microservice em Node:

https://www.loom.com/share/dd1d9922485943a897392b2d7e325522

Atualizado em 26/07/2024.

O arquivo test/global-setup-integration-tests.ts define a função setup que é executada antes de rodar os testes de integração. Neste arquivo, é feito a criação de um novo banco de dados, a execução das migrations e o seed dos dados:

import { PrismaClient } from '@prisma/client';
import { randomUUID } from 'node:crypto';
import { execSync } from 'node:child_process';
import { Redis } from 'ioredis';

export const redisPort = 6380;

const redis = new Redis(redisPort);

const prisma = new PrismaClient();

function generateUniqueDatabaseURL(schemaId: string) {
if (!process.env.DATABASE_URL) {
throw new Error('Please provide a DATABASE_URL environment variable.');
}

const url = new URL(process.env.DATABASE_URL);

url.searchParams.set('schema', schemaId);

return url.toString();
}

const schemaId = randomUUID();

export async function setup() {
await redis.flushall();
const databaseURL = generateUniqueDatabaseURL(schemaId);
process.env.DATABASE_URL = databaseURL;
execSync('npx prisma migrate deploy', { stdio: 'inherit' });
execSync('pnpm seed', { stdio: 'inherit' });
}

export async function teardown() {
console.log('Tearing down...');
await prisma.$executeRawUnsafe(
`DROP SCHEMA IF EXISTS "${schemaId}" CASCADE;`,
);
await prisma.$disconnect();
redis.disconnect();
}

O arquivo test/instance-setup-integration-test.ts define a função setup que é executada antes de rodar cada teste de integração. Neste arquivo, o beforeAll chama o setup do app fixture. O afterAll chama o teardown do app fixture:

import { AppFixture } from './app.fixture';

export let appFixture: AppFixture;

beforeAll(async () => {
appFixture = await AppFixture.setup();
});

afterAll(async () => {
// Waiting for logs to be sent to better stack
await new Promise((resolve) => setTimeout(resolve, 4000));
await appFixture.teardown();
});

O setup do app fixture é definido no arquivo test/app.fixture.ts, nele é feito a criação da aplicação a ser testada:

import { Test } from '@nestjs/testing';
import * as portfinder from 'portfinder';
import { INestApplication } from '@nestjs/common';
import request from 'supertest';
import { lock } from 'simple-redis-mutex';
import { Redis } from 'ioredis';
import { faker } from '@faker-js/faker';
import { redisPort } from './global-setup-integration-tests';
import { PrismaProvider } from '../src/prisma/prisma.provider';
import { CredentialsProvider } from '../src/iam/credentials/credentials.provider';
import { AppModule } from '../src/app.module';
import { setupApp } from '../src/setup';
import { BankConnectionHistoryRange, WorkspaceType } from '@prisma/client';

export class AppFixture {
app: INestApplication;
prismaProvider: PrismaProvider;
credentialsProvider: CredentialsProvider;
redis: Redis;
serverBaseUrl: string;
request: request.SuperTest<request.Test>;

constructor() {
this.redis = new Redis(redisPort);
}

static async setup(): Promise<AppFixture> {
const moduleRef = await Test.createTestingModule({
imports: [AppModule],
}).compile();

const appFixture = new AppFixture();

appFixture.app = moduleRef.createNestApplication();
appFixture.prismaProvider = moduleRef.get(PrismaProvider);
appFixture.credentialsProvider = moduleRef.get(CredentialsProvider);

setupApp(appFixture.app);

while (true) {
try {
const port = await portfinder.getPortPromise();
await appFixture.app.listen(port);
appFixture.serverBaseUrl = `http://localhost:${port}`;
appFixture.request = request(appFixture.serverBaseUrl);
break;
} catch (e) {}
}

return appFixture;
}

// ...
}

Antes de rodar os testes de integração deve-se subir os containers dos bancos de dados. Para tanto, execute o comando:

pnpm setup:integration-test

Para rodar os testes de integração, execute o comando:

pnpm test:integration

Caso você queira rodar apenas um teste específico (testes de workspaces por exemplo), execute o comando:

pnpm test:integration workspaces