Como testar funções assíncronas em JavaScript?

Testar funções assíncronas é uma parte crucial do desenvolvimento moderno em JavaScript. Aprenda a escrever testes com Jest para garantir que funções assíncronas funcionem corretamente.

Como testar funções assíncronas em JavaScript?

Testar funções assíncronas pode ser desafiador, especialmente quando se trata de funções baseadas em promises ou async/await. No entanto, com o uso de ferramentas como Jest, é possível testar facilmente essas funções. Jest fornece APIs poderosas para lidar com código assíncrono, permitindo que você escreva testes claros e eficazes.

Testando funções que retornam Promises

Quando uma função retorna uma promise, você pode usar a função then() ou async/await para esperar pela resolução dessa promise. No Jest, você pode escrever testes que aguardam pela resolução da promise utilizando resolve() ou async/await.

Exemplo de teste de função que retorna uma promise:

function fetchData() {
  return new Promise((resolve) => {
    setTimeout(() => resolve('data'), 1000);
  });
}

test('deve retornar "data" após 1 segundo', () => {
  return fetchData().then((data) => {
    expect(data).toBe('data');
  });
});

O que o código está fazendo: A função fetchData retorna uma promise que resolve a string 'data' após um tempo de 1 segundo. O teste aguarda a resolução da promise usando then(), e em seguida, verifica se o valor retornado é 'data'.

Usando async/await para funções assíncronas

O async/await é uma forma moderna de lidar com promises. Ele permite que você escreva código assíncrono de maneira mais síncrona, o que pode tornar os testes mais fáceis de entender.

Exemplo de teste com async/await:

function fetchData() {
  return new Promise((resolve) => {
    setTimeout(() => resolve('data'), 1000);
  });
}

test('deve retornar "data" com async/await', async () => {
  const data = await fetchData();
  expect(data).toBe('data');
});

O que o código está fazendo: Aqui, a função fetchData() é testada usando async/await. O teste aguarda a promise ser resolvida com await e verifica se o valor retornado é 'data'. O uso de async na função do teste e await dentro dela simplifica o código de espera.

Testando funções assíncronas com Jest e timers

Ao testar funções assíncronas que dependem de temporizadores como setTimeout() ou setInterval(), é importante controlar os timers para evitar delays desnecessários durante a execução dos testes.

Jest fornece funções como jest.useFakeTimers() e jest.runAllTimers() para simular temporizadores e fazer com que o código seja executado instantaneamente durante o teste.

Exemplo de teste com timers:

function fetchData() {
  return new Promise((resolve) => {
    setTimeout(() => resolve('data'), 1000);
  });
}

test('deve retornar "data" imediatamente com jest.useFakeTimers()', () => {
  jest.useFakeTimers();
  const promise = fetchData();
  jest.runAllTimers();
  promise.then((data) => {
    expect(data).toBe('data');
  });
});

O que o código está fazendo: O código utiliza jest.useFakeTimers() para simular os temporizadores e jest.runAllTimers() para forçar a execução de todas as funções agendadas. Dessa forma, o teste é executado de forma imediata, sem esperar os 1000ms de espera da setTimeout().

Testando erros em funções assíncronas

Além de testar o sucesso de funções assíncronas, você também pode testar os erros que elas podem lançar. Isso é importante para garantir que seu código lide corretamente com falhas, como falhas de rede ou erros inesperados.

Exemplo de teste de erro com Jest:

function fetchData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => reject('erro'), 1000);
  });
}

test('deve lançar erro ao buscar dados', async () => {
  try {
    await fetchData();
  } catch (e) {
    expect(e).toBe('erro');
  }
});

O que o código está fazendo: A função fetchData é projetada para rejeitar a promise com a mensagem 'erro'. O teste captura esse erro dentro de um bloco try...catch e usa expect() para verificar se a mensagem de erro é 'erro'.

Conclusão

Testar funções assíncronas em JavaScript pode parecer complicado, mas Jest torna esse processo muito mais simples e intuitivo. Usando async/await, promises, e mocks, você pode testar facilmente funções assíncronas e garantir que seu código está funcionando corretamente, mesmo quando interage com APIs externas ou realiza operações assíncronas.

Testar funções assíncronas é uma habilidade essencial para garantir a qualidade do código em JavaScript. Ferramentas como Jest não apenas simplificam esse processo, mas também oferecem poderosas funções para controlar o comportamento assíncrono, como mocks e timers. Ao escrever testes para promises e funções async/await, você está criando uma base sólida de confiança no comportamento do seu código.

Algumas aplicações:

  • Testar funções assíncronas usando async/await para aguardar resultados de promises.
  • Usar Jest para simular temporizadores e evitar delays durante os testes.
  • Testar o comportamento de funções assíncronas em cenários de erro.

Dicas para quem está começando

  • Foque primeiro em testar funções simples antes de passar para funções mais complexas e assíncronas.
  • Utilize mocks sempre que necessário para isolar o comportamento da função que está sendo testada.
  • Não se esqueça de testar erros em funções assíncronas, para garantir que o código se comporte corretamente em cenários de falha.

Contribuições de Renato Marques

Compartilhe este tutorial: Como testar funções assíncronas em JavaScript?

Compartilhe este tutorial

Continue aprendendo:

Como escrever testes com Jest?

Jest é uma das ferramentas mais populares para testar código JavaScript. Aprenda a escrever testes simples e eficazes com Jest e melhore a qualidade do seu código.

Tutorial anterior

O que são mocks e stubs em testes JavaScript?

Mocks e stubs são ferramentas poderosas para isolar o código em testes JavaScript. Eles ajudam a simular o comportamento de dependências externas, permitindo que você teste a lógica da função isoladamente.

Próximo tutorial