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.
Como simplificar o teste de funções assíncronas com Jest
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