1
resposta

[Dúvida] Uso do '--detectOpenHandles'

Olá, ao executar o comando npm run test:auth:router no terminal, os testes passam normalmente, conforme esperado, porém no final aparece a seguinte mensagem de aviso:

Jest did not exit one second after the test run has completed.

This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with `--detectOpenHandles` to troubleshoot this issue.

Conforme sugerido, adicionei a flag --detectOpenHandles no arquivo package.json:

  "scripts": {
    "dev": "nodemon server.js",
    "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
    "test:watch": "node --experimental-vm-modules node_modules/jest/bin/jest.js --watchAll",
    "test:coverage": "node --experimental-vm-modules node_modules/jest/bin/jest.js --watchAll --coverage",
    "test:auth:service": "node --experimental-vm-modules node_modules/jest/bin/jest.js --testPathPattern=src/test/services/authService.test.js",
    "test:auth:router": "node --experimental-vm-modules node_modules/jest/bin/jest.js --testPathPattern=src/test/routes/authRoutes.test.js --detectOpenHandles"
  }

Ao rodar o comando npm run test:auth:router novamente no terminal a seguinte mensagem aparece:

Jest has detected the following 1 open handle potentially keeping Jest from exiting:

  ●  bound-anonymous-fn

       9 | beforeEach(() => {
      10 |   const port = 3000;
    > 11 |   server = app.listen(port);
         |                ^
      12 | });
      13 | // Encerrar o servidor após a finalziação dos testes
      14 | afterEach(() => {

      at Function.listen (node_modules/express/lib/application.js:635:24)
      at Object.listen (src/test/routes/authRoutes.test.js:11:16)
      at TestScheduler.scheduleTests (node_modules/@jest/core/build/TestScheduler.js:317:13)
      at runJest (node_modules/@jest/core/build/runJest.js:407:19)
      at _run10000 (node_modules/@jest/core/build/cli/index.js:339:7)
      at runCLI (node_modules/@jest/core/build/cli/index.js:190:3)

Apesar da mensagem não atrapalhar os testes realizados, fiquei na dúvida sobre o que seria esse problema indicado e como poderia solucionar.

Segue o arquivo authService.test.js:

import request from 'supertest';
import { afterEach, beforeEach, describe } from '@jest/globals';
import app from '../../app';

let server;
// Iniciar o servirdor na porta 3000 antes da realização dos testes
beforeEach(() => {
  const port = 3000;
  server = app.listen(port);
});
// Encerrar o servidor após a finalziação dos testes
afterEach(() => {
  server.close();
});

describe('Testando a rota login POST', () => {
  it('O login deve possuir um e-mail e senha para se autenticar', async () => {
    // Arrange
    const loginMock = {
      email: 'raphael@teste.com.br',
    };
    // Assert
    await request(server)
      .post('/login')
      .send(loginMock)
      .expect(500)
      .expect('"A senha de usuario é obrigatório."');
  });

  it('O login deve validar se o usuário está cadastrado', async () => {
    // Arrange
    const loginMock = {
      email: 'gabriel@teste.com', // email certo: gabriel@teste.com.br
      senha: 'gab12345',
    };
    // Assert
    await request(server)
      .post('/login')
      .set('Accept', 'application/json')
      .send(loginMock)
      .expect(500)
      .expect('"Usuario não cadastrado."');
  });

  it('O login deve validar e-mail e senha incorreto', async () => {
    // Arrange
    const loginMock = {
      email: 'gabriel@teste.com.br',
      senha: 'gab1234', // senha certa: gab12345
    };
    // Assert
    await request(server)
      .post('/login')
      .set('Accept', 'application/json')
      .send(loginMock)
      .expect(500)
      .expect('"Usuario ou senha invalido."');
  });

  it('O login deve validar se esta sendo retornado um accessToken', async () => {
    // Arrange
    const loginMock = {
      email: 'gabriel@teste.com.br',
      senha: 'gab12345',
    };
    // Assert
    const resposta = await request(server)
      .post('/login')
      .set('Accept', 'application/json')
      .send(loginMock)
      .expect(201);
    expect(resposta.body.message).toBe('Usuário conectado');
    expect(resposta.body).toHaveProperty('accessToken');
  });
});
1 resposta

Olá Gabriel, tudo joia?

Isso geralmente ocorre quando há operações assíncronas que não foram completamente encerradas após os testes. No seu caso, parece que o servidor Express está sendo iniciado antes dos testes, mas não está sendo fechado corretamente após cada teste, mesmo com o server.close() no afterEach.

Então, caso queira ajustar isso para garantir que o servidor seja corretamente fechado, você pode seguir a seguinte sugestão de modificação no seu código:

import request from 'supertest';
import { afterEach, beforeEach, describe } from '@jest/globals';
import app from '../../app';

let server;
let port = 3000;

// Iniciar o servidor na porta 3000 antes da realização dos testes
beforeEach((done) => {
  server = app.listen(port, done);
});

// Encerrar o servidor após a finalização dos testes
afterEach((done) => {
  server.close(done);
});

describe('Testando a rota login POST', () => {
  it('O login deve possuir um e-mail e senha para se autenticar', async () => {
    // Arrange
    const loginMock = {
      email: 'raphael@teste.com.br',
    };
    // Assert
    await request(server)
      .post('/login')
      .send(loginMock)
      .expect(500)
      .expect('"A senha de usuario é obrigatório."');
  });

  it('O login deve validar se o usuário está cadastrado', async () => {
    // Arrange
    const loginMock = {
      email: 'gabriel@teste.com', // email certo: gabriel@teste.com.br
      senha: 'gab12345',
    };
    // Assert
    await request(server)
      .post('/login')
      .set('Accept', 'application/json')
      .send(loginMock)
      .expect(500)
      .expect('"Usuario não cadastrado."');
  });

  it('O login deve validar e-mail e senha incorreto', async () => {
    // Arrange
    const loginMock = {
      email: 'gabriel@teste.com.br',
      senha: 'gab1234', // senha certa: gab12345
    };
    // Assert
    await request(server)
      .post('/login')
      .set('Accept', 'application/json')
      .send(loginMock)
      .expect(500)
      .expect('"Usuario ou senha invalido."');
  });

  it('O login deve validar se esta sendo retornado um accessToken', async () => {
    // Arrange
    const loginMock = {
      email: 'gabriel@teste.com.br',
      senha: 'gab12345',
    };
    // Assert
    const resposta = await request(server)
      .post('/login')
      .set('Accept', 'application/json')
      .send(loginMock)
      .expect(201);
    expect(resposta.body.message).toBe('Usuário conectado');
    expect(resposta.body).toHaveProperty('accessToken');
  });
});

A principal mudança aqui é que agora estou passando uma função done para os métodos beforeEach e afterEach. Isso garante que o Jest espere até que o servidor seja completamente iniciado ou fechado antes de continuar.

Espero ter ajudado e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.