# Unit & Integration Testing

## Framework Comparison

| Framework | Speed | Best For |
|-----------|-------|----------|
| Vitest | Fastest | Modern projects, Vite |
| Jest | Fast | React/CRA legacy |
| Bun test | Ultra-fast | Bun projects |

## Vitest Setup

```typescript
// vitest.config.ts
export default defineConfig({
  test: {
    environment: 'jsdom', // or 'happy-dom'
    globals: true,
    coverage: { reporter: ['text', 'json', 'html'] },
  },
});
```

## Vitest Browser Mode (Real Browser)

```typescript
// vitest.config.ts - higher fidelity than jsdom
export default defineConfig({
  test: {
    browser: {
      enabled: true,
      name: 'chromium',
      provider: 'playwright',
    },
  },
});
```

**When to use:** Complex DOM interactions, CSS testing, browser APIs

## Test Structure (AAA)

```typescript
import { describe, it, expect, beforeEach } from 'vitest';

describe('UserService', () => {
  let service: UserService;

  beforeEach(() => {
    service = new UserService();
  });

  it('creates user with valid data', () => {
    // Arrange
    const userData = { email: 'test@example.com' };

    // Act
    const user = service.create(userData);

    // Assert
    expect(user.id).toBeDefined();
    expect(user.email).toBe('test@example.com');
  });

  it('throws on invalid email', () => {
    expect(() => service.create({ email: 'invalid' }))
      .toThrow('Invalid email');
  });
});
```

## Integration Test

```typescript
describe('User API', () => {
  let db: Database;

  beforeAll(async () => {
    db = new Database(':memory:');
    await db.migrate();
  });

  afterEach(async () => {
    await db.clearAllTables();
  });

  it('persists and retrieves user', async () => {
    await db.users.insert({ email: 'test@example.com' });
    const user = await db.users.findOne({ email: 'test@example.com' });
    expect(user).toBeDefined();
  });
});
```

## Test Naming

```typescript
// Good - describes behavior
it('should return 200 when valid token provided');
it('should throw ValidationError when email invalid');

// Bad - vague
it('test1');
it('works');
```

## Mocking

```typescript
import { vi } from 'vitest';

// Mock module
vi.mock('./api', () => ({
  fetchUser: vi.fn().mockResolvedValue({ name: 'John' })
}));

// Spy
const spy = vi.spyOn(console, 'log');
expect(spy).toHaveBeenCalledWith('message');
```

## Coverage Targets

| Area | Target |
|------|--------|
| Critical paths | 100% |
| Core features | 80-90% |
| Overall | 75-85% |

## Commands

```bash
npx vitest run              # Run all
npx vitest                  # Watch mode
npx vitest run --coverage   # Coverage
npx vitest run -u           # Update snapshots
npx vitest --browser        # Browser mode
```
