Skip to main content

Como fazer testes com Vitest

Este guia tem como objetivo orientar a equipe na escrita de testes unitários eficazes, com foco em qualidade, manutenção e confiança no código. Serve como referência para consulta rápida e como base para estudos.

Antes de criar um teste é interessante pensar em um checklist para garantir que todos os cenários importantes serão cobertos:

  • Testa o fluxo principal de sucesso?
  • Testa erros e exceções?
  • Testa entradas inválidas?
  • Testa o comportamento esperado, não detalhes internos?
  • Usa mocks apenas quando necessário?
  • Tem nomes claros e descritivos?
  • Evita repetições desnecessárias?
  • Executa rápido?

✨ Criando um arquivo de teste​

  • Crie um diretório: __tests__.
  • Neste diretório, crie um arquivo: arquivo.test.ts.

✨ Como executar os testes​

  • Para executar todos os teste de um só vez: pnpm run test
  • Para executar os teste de um diretório específico: pnpm run test src/pasta-especifica
  • Para executar os teste de um arquivo específico: pnpm run test src/pasta-especifica/arquivo.test.ts

✨ Estrutura padrão​

import { describe, it, expect, beforeEach, vi } from 'vitest';

describe('nome da funcionalidade ou do módulo', () => {
beforeAll(() => {
// Executado uma vez antes de todos os testes
});

beforeEach(() => {
// Executado antes de cada teste
});

afterEach(() => {
// Executado após cada teste
});

afterAll(() => {
// Executado uma vez após todos os testes
});

it('deve fazer algo esperado', () => {
// Arrange: preparar o cenário
// Act: executar o comportamento
// Assert: verificar o resultado
});

it('deve lidar com casos de erro', () => {
// Outro caso de teste
});
});

Exemplo de um teste simples​

import { describe, it, expect, vi, beforeEach } from 'vitest';
import { somar } from '../utils/matematica';

describe('Função somar', () => {
it('deve retornar a soma de dois números', () => {
expect(somar(2, 3)).toBe(5);
});
});

✨ Exemplos comparativos​

Teste ruim: Nome genérico, não se sabe o que está testando, pouca assertividade.

it('deve funcionar', () => {
const result = minhaFuncao();
expect(result).toBeTruthy();
});

Teste mediano: Melhor, mas a expectativa poderia ser mais precisa.

it('deve retornar valor positivo', () => {
const result = minhaFuncao(5);
expect(result > 0).toBe(true);
});

Teste bom: Clareza, expectativa precisa, descritivo.

it('deve retornar 10 quando entrada for 5', () => {
const result = minhaFuncao(5);
expect(result).toBe(10);
});

✨ Mocking avançado com Vitest​

Situação: Mockar dependência externa (ex: API ou serviço)​

import { fetchData } from './api';
vi.mock('./api');

it('deve retornar dados processados da API', async () => {
fetchData.mockResolvedValue({ value: 5 });

const result = await minhaFuncao();

expect(fetchData).toHaveBeenCalled();
expect(result).toBe(10);
});

Pontos positivos: Mock claro, assertivo, comportamento validado.


✨ Testes de API​

vi.stubGlobal('fetch', vi.fn().mockResolvedValue({
json: async () => ({ x: 1 })
}));

it('deve retornar x processado', async () => {
const result = await minhaApi();
expect(fetch).toHaveBeenCalledWith('/endpoint');
expect(result).toEqual({ x: 2 });
});

Pontos positivos: Controle total da resposta, verificação de comportamento e retorno.


✨ Testando falhas e validações negativas​

Testar apenas casos de sucesso não garante a robustez do sistema. Testes negativos validam se o sistema reage corretamente a entradas inválidas ou erros.

Validações Síncronas​

it('deve lançar "Entrada inválida" se valor for vazio', () => {
expect(() => minhaFuncao('')).toThrow('Entrada inválida');
});

Pontos positivos: Valida mensagem de erro esperada, comportamento previsível.

Validações em Requisições Assíncronas​

it('deve lançar erro se requisição falhar', async () => {
vi.stubGlobal('fetch', vi.fn().mockRejectedValue(new Error('Falha na requisição')));

await expect(minhaApi()).rejects.toThrow('Falha na requisição');
});

it('deve capturar erro com try/catch', async () => {
vi.stubGlobal('fetch', vi.fn().mockRejectedValue(new Error('Erro de rede')));

try {
await minhaApi();
} catch (e) {
expect(e.message).toBe('Erro de rede');
}
});

Pontos positivos: Testa falhas reais, assegura tratamento correto de erros assíncronos.

🧑‍💻 Referências Rápidas​


✅ Conclusão​

Testes não são apenas uma exigência, mas uma ferramenta para manter e evoluir o projeto com segurança e qualidade. Escrever bons testes é uma habilidade que melhora com prática e colaboração.