Skill: Testes Unitários - Angular + Vitest
Descrição
Cria, corrige, completa ou revisa testes unitários com Vitest em qualquer projeto Angular, cobrindo componentes, services, effects, reducers, selectors, facade, signal stores e utilitários.
Quando usar
Use esta skill quando o usuário pedir para criar, corrigir, completar ou revisar testes unitários com Vitest em qualquer arquivo de um projeto Angular.
Stack e configurações
- Framework de testes: Vitest (Vite-native, Jest-compatible)
- Arquivos: *.spec.ts ou *.test.ts (configurável)
- Configuração: "vitest.config.ts" ou "vite.config.ts" com bloco test
- Setup: "setup-vitest.ts" ou "setup.ts" (configurável)
- Cobertura: "@vitest/coverage-v8" ou "@vitest/coverage-istanbul"
- Assertions: Built-in Chai + jest-compatible API
Comandos Úteis
# Rodar teste específico (SEMPRE usar node direto - NUNCA npx vitest!)
node "path/do/projeto/node_modules/vitest/vitest.mjs" run "caminho/do/arquivo.spec.ts"
# Filtrar describe específico
node "path/vitest.mjs" run "arquivo.spec.ts" -t "^NomeDoDescribe(\s.*)?$"
# Cobertura silenciosa
npx vitest run <pasta> --coverage --silent
# Cobertura com tabela
npx vitest run src/app/<mod> --coverage --silent --reporter=default --no-file-parallelism --coverage.reporter=text --coverage.include="src/app/<mod>/**/*.ts"
⚠️ REGRA: NUNCA usar npx vitest run <arquivo> para arquivos específicos (falha por resolução de módulos). Usar SEMPRE node direto.
Detectar Framework de Teste
O orquestrador DEVE detectar automaticamente qual framework está configurado:
Verificar package.json do projeto:
- Se tiver
"vitest"nas devDependencies → Vitest - Se tiver
"jest"ou"@angular/cli"com jest → Jest - Se tiver ambos → Perguntar ao usuário qual usar
- Se tiver
Verificar arquivos de configuração:
vitest.config.tsouvitest.config.js→ Vitestjest.config.tsoujest.config.js→ Jestangular.jsoncom"test": { "builder": "@angular-builders/jest:run" }→ Jestangular.jsoncom"test": { "builder": "@angular-builders/vitest:run" }→ Vitest
Se não encontrar nenhum → Perguntar ao usuário qual framework usar
Regras Simples - Sempre Valer
Use
vido Vitest para mocks (nãojest):vi.fn()para criar mocksvi.mock()para mockar módulosvi.spyOn()para espiar métodosvi.restoreAllMocks()para restaurar
Configure
restoreMocks: trueno vitest.config.ts para limpeza automáticaUse
vi.mock(import('./module'))em vez de strings para type safetyUse
vi.hoisted()quando precisar de factories antes dos importsPara services Angular, use
mockProvider()do@vitest/angularou crie mocks manualmentePara componentes, use
TestBed.configureTestingModule()com imports necessáriosPrefira
TestBed.inject()em vez deTestBed.get()(deprecated)Use
fixture.detectChanges()para trigger ngOnInitPara signals, use
fixture.componentRef.setInput()efixture.componentRef.getInput()Agrupar testes com
describe, usaritoutestpara cada caso
Padrões de Mock
Services Angular
import { vi } from 'vitest'
const mockService = {
metodo: vi.fn()
}
await TestBed.configureTestingModule({
providers: [
{ provide: ServiceName, useValue: mockService }
]
}).compileComponents();
HTTP Calls (MSW)
import { http, HttpResponse } from 'msw'
import { setupServer } from 'msw/node'
const server = setupServer(
http.get('/api/endpoint', () => {
return HttpResponse.json({ data: 'mocked' })
})
)
beforeAll(() => server.listen({ onUnhandledRequest: 'error' }))
afterAll(() => server.close())
afterEach(() => server.resetHandlers())
Módulos
vi.mock(import('./service'), () => ({
ServiceName: vi.fn().mockImplementation(() => ({
metodo: vi.fn()
}))
}))
Signals
component.signalName.set(value)
expect(component.signalName()).toBe(value)
Espiando Métodos
const spy = vi.spyOn(object, 'method')
expect(spy).toHaveBeenCalledWith(args)
Estrutura de Teste Padrão
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { describe, it, expect, beforeEach } from 'vitest';
import { ComponentName } from './component-name';
describe('ComponentName', () => {
let component: ComponentName;
let fixture: ComponentFixture<ComponentName>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [ComponentName],
providers: []
}).compileComponents();
fixture = TestBed.createComponent(ComponentName);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should [comportamento esperado]', () => {
// Arrange
// Act
// Assert
});
});
Configuração Recomendada (vitest.config.ts)
Opção 1: Com @analogjs/vite-plugin-angular (se disponível)
import { defineConfig } from 'vitest/config'
import angular from '@analogjs/vite-plugin-angular'
export default defineConfig({
plugins: [angular()],
test: {
globals: true,
environment: 'jsdom',
include: ['src/**/*.spec.ts', 'src/**/*.test.ts'],
setupFiles: ['src/setup-vitest.ts'],
restoreMocks: true,
coverage: {
provider: 'v8',
reporter: ['text', 'json', 'html'],
include: ['src/**/*.ts'],
exclude: ['src/**/*.spec.ts', 'src/**/*.test.ts', 'src/main.ts', 'src/polyfills.ts']
}
}
})
Opção 2: Sem @analogjs (alternativa genérica)
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
globals: true,
environment: 'jsdom',
include: ['src/**/*.spec.ts', 'src/**/*.test.ts'],
restoreMocks: true,
coverage: {
provider: 'v8',
reporter: ['text', 'json', 'html'],
include: ['src/**/*.ts'],
exclude: ['src/**/*.spec.ts', 'src/**/*.test.ts', 'src/main.ts', 'src/polyfills.ts']
}
}
})
Setup File (setup-vitest.ts)
Opção 1: Com @analogjs (se disponível)
import '@analogjs/vitest-zone-r8'
Opção 2: Sem @analogjs (alternativa)
// Configuração básica para Angular + Vitest
// Se precisar de Zone.js, importe manualmente
Tipos de Teste
Componentes
- Criação
- Renderização
- Interações (click, input)
- Outputs/Events
- Inputs/Props
- Lifecycle hooks
Services
- Métodos públicos
- Tratamento de erros
- Chamadas HTTP
- States/Signals
Pipes
- Transformação
- Casos extremos
Guards
- Retorno true/false
- Redirecionamento
Quando não usar
- Para testes de integração usar "cypress" ou "playwright"
- Para testes de performance usar ferramentas específicas
- Para testes visuais usar "storyshot" ou similar
Saída Esperada
Arquivo .spec.ts ou .test.ts seguindo padrão do projeto, com:
- Imports corretos (vitest em vez de jest)
- Configuração adequada do TestBed
- Mocks usando vi.fn(), vi.mock(), vi.spyOn()
- Testes cobrindo cenários principais
- Organização clara (describe, it/test, expect)