Garantir a qualidade do código é essencial para qualquer projeto em JavaScript ou TypeScript, especialmente quando estamos desenvolvendo com React. Testes bem escritos evitam bugs, facilitam refatoramentos e trazem confiança na evolução do sistema.
• 02 de mai. de 2025
• 8 min de leitura
Neste artigo, vamos explorar como testar funções simples, funções assíncronas (async/await, Promise), componentes React com hooks e estado utilizando @testing-library/react
Testando Funções Simples
Funções puras (sem efeitos colaterais) são as mais fáceis de testar. Vamos ver um exemplo básico:
// utils/math.tsexportfunctionsoma(a:number, b:number):number{return a + b;}
O teste pode ser escrito assim:
// utils/math.test.tsimport{ soma }from'./math';describe('Função soma',()=>{it('deve somar dois números corretamente',()=>{expect(soma(2,3)).toBe(5);});});
Dica:
Evite testar funções triviais em excesso (como soma ou multiplicação) no mundo real, a menos que elas façam parte da regra de negócio crítica.
Testando Funções Assíncronas
Testes assíncronos exigem um pouco mais de atenção. Vamos usar uma função que simula uma requisição HTTP:
// api/user.tsexportasyncfunctiongetUserName(id:number):Promise<string>{const response =awaitfetch(`/api/users/${id}`);const data =await response.json();return data.name;}
Podemos mockar o fetch no teste:
// api/user.test.tsimport{ getUserName }from'./user';describe('getUserName',()=>{beforeEach(()=>{ global.fetch= vi.fn().mockResolvedValue({json:()=>Promise.resolve({ name:'João'})})asany;});it('retorna o nome do usuário',async()=>{const name =awaitgetUserName(1);expect(name).toBe('João');});});
Dica:
Use jest.fn() para simular comportamentos de funções externas. Use await ou return no it() para garantir que o Jest espere a Promise.
Testando Componentes com Estado e Hooks
Para React, usamos muito @testing-library/react por ser focada em boas práticas de testes baseados em comportamento do usuário.
// components/Counter.test.tsximport{ render, screen, fireEvent }from'@testing-library/react';import{Counter}from'./Counter';describe('Counter',()=>{it('deve mostrar valor inicial e incrementar ao clicar',()=>{render(<Counter/>);expect(screen.getByText(/valor atual: 0/i)).toBeInTheDocument();const button = screen.getByText(/incrementar/i); fireEvent.click(button);expect(screen.getByText(/valor atual: 1/i)).toBeInTheDocument();});});
Dica:
Uma boa prática ao testar componentes com @testing-library/react é evitar seletores baseados em classes ou IDs, e preferir buscar os elementos da forma como o usuário final os encontraria na tela. Por exemplo, usar screen.getByText, screen.getByRole ou screen.getByLabelText torna os testes mais legíveis e confiáveis. Isso também ajuda a manter os testes mais robustos contra mudanças estéticas. Além disso, é importante não se prender à implementação interna do componente, como estados ou funções internas. O foco dos testes deve estar em como o componente se comporta do ponto de vista do usuário. Para simular essas interações reais, você pode usar fireEvent ou a biblioteca userEvent, que oferece uma simulação mais próxima do comportamento humano (como digitação e clique).
Testando Hooks Personalizados
Hooks personalizados são testados com @testing-library/react-hooks ou criando componentes wrapper.
// hooks/useToggle.test.tsximport{ renderHook, act }from'@testing-library/react';import{ useToggle }from'./useToggle';describe('useToggle',()=>{it('deve alternar o valor booleano',()=>{const{ result }=renderHook(()=>useToggle());expect(result.current.value).toBe(false);act(()=> result.current.toggle());expect(result.current.value).toBe(true);});});
Testar componentes e funções é uma etapa essencial no desenvolvimento de aplicações modernas. Funções simples devem ser verificadas com entradas e saídas bem definidas, garantindo que se comportem conforme esperado diante de diferentes cenários. Quando lidamos com funções assíncronas, é importante redobrar a atenção com o uso de await e a criação de mocks adequados para simular dependências externas como chamadas HTTP.
No caso dos componentes React, a melhor abordagem é escrever testes com foco no comportamento visível e interações do usuário, deixando de lado detalhes internos da implementação como estados ou funções privadas. Essa abordagem torna os testes mais robustos, fáceis de manter e alinhados com a experiência real do usuário final.
Dedicar tempo à escrita de testes confiáveis não só ajuda a prevenir bugs, mas também torna o processo de evolução do código mais seguro e tranquilo. No fim, os testes funcionam como uma rede de segurança que permite ao desenvolvedor trabalhar com mais confiança.
Tags
Jest
Artigos Relacionados
Jest
Test Driven Development (TDD) com Jest
Test Driven Development, mais conhecido como TDD, é uma abordagem de desenvolvimento de software onde os testes são escritos antes do código de produção. O objetivo principal do TDD é garantir que cada parte do sistema seja testada de forma automatizada, tornando o processo de desenvolvimento mais seguro, previsível e de alta qualidade.
22 de mai. de 20258 min de leitura
Jest
Debugging com Jest: Guia Completo para Solucionar Testes Falhando
Testes falhando são comuns durante o desenvolvimento de software, e depurá-los rapidamente é essencial para produtividade. Neste guia, você vai aprender como utilizar o Chrome DevTools para depurar testes Jest e descobrirá as melhores práticas para resolver problemas comuns de forma eficiente.
20 de mai. de 20255 min de leitura
Jest
Cobertura de Testes com Jest (--coverage)
A cobertura de testes, ou coverage, é uma métrica que mede o quanto do seu código está sendo testado por testes automatizados. Quando você executa testes com Jest utilizando a flag --coverage, ele gera um relatório detalhado que mostra quais partes do seu código estão ou não sendo testadas. Entender esse relatório é fundamental para garantir a qualidade e a segurança da sua aplicação.
16 de mai. de 20256 min de leitura
Jest
Testando Código Assíncrono com Jest
É comum em JavaScript executar código de forma assíncrona. Quando você tiver código assíncrono, o Jest precisa saber quando ele foi concluído para então seguir com os testes seguintes. Felizmente, o Jest oferece várias formas de lidar com isso.