Executando verificação de segurança...
1

Migrei para pool de conexão e levei um bug bizarro do Jest logo de cara

Estava refatorando minha aplicação Node.js para usar pg.Pool no lugar de conexões avulsas — o ganho de performance em queries concorrentes é real e vale a mudança. Mas logo nos primeiros testes, algo quebrou de um jeito que não fazia sentido nenhum.

O cenário

Tenho um teste que valida a expiração de um token de ativação. A lógica é simples: criar um token com expires_at no passado e verificar que a autenticação falha. Para isso, uso jest.useFakeTimers() para controlar o Date.now().

O teste funcionava perfeitamente antes do pool. Depois da migração, começou a falhar de formas aleatórias — às vezes um timeout, às vezes uma query retornando resultado errado, às vezes o teste travando sem terminar.

Por que jest.useFakeTimers() quebra o pool?

O problema é específico — e não óbvio.

jest.useFakeTimers() substitui todas as funções de timer por padrão: setTimeout, clearTimeout, setInterval etc. O pg.Pool usa esses timers internamente para gerenciar idleTimeoutMillis e connectionTimeoutMillis.

Quando você chama client.release() com fake timers ativos, o pool registra o idle timer usando o setTimeout falso. Quando jest.useRealTimers() é chamado depois, esse timer some — a conexão fica no pool sem idle timer. Na próxima query, coisas estranhas acontecem.

A solução

A solução correta é a que o próprio Jest oferece: doNotFake. Faça fake só do Date e deixe os timers reais:

jest.useFakeTimers({
  doNotFake: [
    'setTimeout',
    'clearTimeout',
    'setInterval',
    'clearInterval',
    'setImmediate',
    'clearImmediate',
  ],
  now: new Date(Date.now() - activation.EXPIRATION_IN_MILLISECONDS - 1000),
});

Assim, Date.now() retorna uma data no passado (o token é criado com expires_at já expirado), mas o pg.Pool continua usando timers reais sem interferência.

Resumo

AbordagemProblema
jest.useFakeTimers() puroSubstitui os timers do pg.Pool → comportamento imprevisível
jest.useFakeTimers({ doNotFake: [...] })Só faz fake do Date → pool funciona normalmente

Se você usa pg.Pool e tem testes que dependem de controle de tempo, vai cair nessa armadilha. O doNotFake resolve limpo.

Carregando publicação patrocinada...