| name | testing-typescript |
| description | TypeScript testing with Vitest/Jest: file structure, mocking strategy, async patterns, and coverage targets |
Testing — TypeScript
Framework
- Vitest for new projects (fast, native ESM, Jest-compatible API).
- Jest only if already configured — don't mix frameworks.
- Run:
vitest run / vitest run --coverage
File Conventions
- Co-locate:
src/utils/format.ts → src/utils/format.test.ts
- Shared fixtures:
tests/fixtures/ or src/__tests__/helpers/
Test Structure
describe('formatDate', () => {
it('should return ISO date string when given a valid Date', () => {
const date = new Date('2026-01-15');
const result = formatDate(date);
expect(result).toBe('2026-01-15');
});
});
Mocking
vi.mock('../services/emailService');
const spy = vi.spyOn(mailer, 'send').mockResolvedValue(undefined);
afterEach(() => vi.restoreAllMocks());
beforeEach(() => vi.useFakeTimers());
afterEach(() => vi.useRealTimers());
Async Tests
it('should reject with AuthError when token is expired', async () => {
expect.assertions(1);
await expect(verifyToken('expired')).rejects.toThrow('Token expired');
});
Coverage Targets
- Business logic: 85%+ branch coverage.
- Utility functions: 100% line coverage.
- Do not write tests just to hit numbers — test behavior.