
Jest
Testando Funções e Componentes no React
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.ts export function soma(a: number, b: number): number { return a + b; }
O teste pode ser escrito assim:
// utils/math.test.ts import { 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.ts export async function getUserName(id: number): Promise<string> { const response = await fetch(`/api/users/${id}`); const data = await response.json(); return data.name; }
Podemos mockar o fetch
no teste:
// api/user.test.ts import { getUserName } from './user'; describe('getUserName', () => { beforeEach(() => { global.fetch = vi.fn().mockResolvedValue({ json: () => Promise.resolve({ name: 'João' }) }) as any; }); it('retorna o nome do usuário', async () => { const name = await getUserName(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.
Exemplo de componente:
// components/Counter.tsx import React, { useState } from 'react'; export function Counter() { const [count, setCount] = useState(0); return ( <div> <p>Valor atual: {count}</p> <button onClick={() => setCount(count + 1)}>Incrementar</button> </div> ); }
Teste:
// components/Counter.test.tsx import { 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.ts import { useState } from 'react'; export function useToggle(initial = false) { const [value, setValue] = useState(initial); const toggle = () => setValue((v) => !v); return { value, toggle }; }
// hooks/useToggle.test.tsx import { 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



