DEV Community

Cover image for Configurando testes de integração no Nestjs com o Typeorm
Yan.ts
Yan.ts

Posted on

Configurando testes de integração no Nestjs com o Typeorm

Teste de integração

Testes de integração como o nome já dá uma noção, são testes integrados com serviços externos, então por exemplo: em um teste unitário eu faço o mock do retorno do banco de dados para não precisar me conectar no banco de dados e fazer as queries. Enquanto nos testes de integração a ideia é subir um banco de dados separado só para teste e rodar e depois destruir esse banco.

Por que usar o teste de integração? tive essa necessidade principalmente pois os testes unitários não me deixaram confortável em garantir o pleno funcionamento da aplicação. Em alguns endpoints onde a função principal era fazer uma busca paginada por exemplo os testes unitários não bastavam pois o que mais importa nessa função é a querie que vai rodar no banco e as suas variações com filtros, e no teste unitário como eu que defino o retorno que a função vai ter não ia ter como testar isso.

Fazendo as configurações

Primeiro precisei configurar uma conexão 'mãe' que vai ser responsável por criar o banco de dados, e também configurar uma conexão secundaria que vai ser a conexão com o banco de testes

const masterConnection = new DataSource({ type: 'postgres', database: process.env.DATABASE_NAME, host: process.env.DATABASE_HOST, password: process.env.DATABASE_PASSWORD, port: process.env.DATABASE_PORT ? parseInt(process.env.DATABASE_PORT, 10) : undefined, username: process.env.DATABASE_USERNAME, entities: ['dist/**/*.entity{.ts,.js}'], migrations: ['dist/src/db/migrations/*.js'], logging: false, name: 'master', migrationsRun: false, }); const connection = new DataSource({ ...(masterConnection.options as PostgresConnectionOptions), database: databaseName, migrationsRun: true, name: undefined, }); 
Enter fullscreen mode Exit fullscreen mode

e então fiz uma função para fazer a conexão e criar o banco de dados o banco de dados e gerei um nome aleatório para o banco

Não é obrigatório gerar um nome aleatório pois ainda vou apagar o banco de testes quando acabar com teste poderia também ser um nome definido como 'test_db' por exemplo

Nessa função fazemos a conexão que vai gerar o banco, geramos ele e retornamos a conexão com esse banco gerado

const databaseName = `test_${randomBytes(8).toString('hex')}`; export async function databaseIntegrationSetup() { try { await masterConnection.initialize(); await masterConnection.query(`CREATE DATABASE "${databaseName}"`); } catch (err) { process.stderr.write( `${err instanceof Error ? err.stack : JSON.stringify(err)}\n`, ); process.exit(1); } return connection; } 
Enter fullscreen mode Exit fullscreen mode

E uma função para fechar a conexão com o banco de dados, onde ele dropa o database criado para testes e fecha a conexão

export async function closeDatabaseIntegrationConnections() { try { await masterConnection.query(`DROP DATABASE "${databaseName}"`); await masterConnection.destroy(); } catch (err) { process.stderr.write( `${err instanceof Error ? err.stack : JSON.stringify(err)}\n`, ); process.exit(1); } } 
Enter fullscreen mode Exit fullscreen mode

Inicializando o teste

describe('Integrations tests', () => { let app: INestApplication; jest.setTimeout(30000); beforeAll(async () => { const databaseConnection = await databaseIntegrationSetup(); const module: TestingModule = await Test.createTestingModule({ imports: [TypeOrmModule.forRoot(databaseConnection.options)], }).compile(); app = module.createNestApplication(); await app.init(); }); afterAll(async () => { await app.close(); await closeDatabaseIntegrationConnections(); }); it('should be defined', async () => { expect(app).toBeDefined(); }); }); 
Enter fullscreen mode Exit fullscreen mode

Para definirmos o teste a gente basicamente vai pegar a conexão com o database que retornamos na primeira função e vamos declarar um modulo de testes e passar essa conexão para o modulo do Typeorm, e vamos inicializar o app nesse momento o teste já vai passar, porem depois de todos os testes rodarem precisamos fechar o app e chamar a função de fechar a conexão com o banco de dados e apagar esse banco criado só para testes

Top comments (0)