Claude Skills
CollectionsCompareWorkflowsNominate
Sign inSign up
© 2026 Curated Agent Skills·Learn more about Agent Skills
Back to repository

unit-testing

verified

Unit testing and TDD expert for Vitest/Jest. Red-green-refactor workflow, mocking strategies, coverage analysis, and ESM mocking patterns. Use for writing tests, implementing TDD, or setting up test coverage.

View on GitHub

Marketplace

specweave

anton-abyzov/specweave

Plugin

sw-testing

development

Repository

anton-abyzov/specweave
31stars

plugins/specweave-testing/skills/unit-testing/SKILL.md

Last Verified

February 4, 2026

Install Skill

Select agents to install to:

Scope:
npx add-skill https://github.com/anton-abyzov/specweave/blob/main/plugins/specweave-testing/skills/unit-testing/SKILL.md -a claude-code --skill unit-testing

Installation paths:

Claude
.claude/skills/unit-testing/
Powered by add-skill CLI

Instructions

# Unit Testing & TDD Expert - Vitest/Jest

## Test-Driven Development (TDD)

### Red-Green-Refactor Cycle

```typescript
// 1. RED: Write failing test
describe('Calculator', () => {
  it('should add two numbers', () => {
    const calc = new Calculator();
    expect(calc.add(2, 3)).toBe(5); // FAILS - doesn't exist
  });
});

// 2. GREEN: Minimal implementation
class Calculator {
  add(a: number, b: number): number {
    return a + b;
  }
}

// 3. REFACTOR: Improve design
class Calculator {
  add(...numbers: number[]): number {
    return numbers.reduce((sum, n) => sum + n, 0);
  }
}
```

### TDD Checklist

- [ ] RED: Test fails for the RIGHT reason
- [ ] GREEN: Simplest code that passes
- [ ] REFACTOR: All tests still green

## Basic Test Structure

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

describe('UserService', () => {
  let service: UserService;

  beforeEach(() => {
    service = new UserService();
    vi.clearAllMocks();
  });

  it('should create user', () => {
    const user = service.create({ name: 'John', email: 'john@test.com' });

    expect(user).toMatchObject({
      id: expect.any(String),
      name: 'John',
      email: 'john@test.com'
    });
  });

  it('should throw for invalid email', () => {
    expect(() => service.create({ email: 'invalid' })).toThrow('Invalid email');
  });
});
```

## Mocking Strategies

### 1. Mock Functions

```typescript
const mockFn = vi.fn();
mockFn.mockReturnValue(42);
expect(mockFn()).toBe(42);
expect(mockFn).toHaveBeenCalledTimes(1);
```

### 2. Mock Modules

```typescript
vi.mock('./database', () => ({
  query: vi.fn().mockResolvedValue([{ id: 1 }])
}));

import { query } from './database';
```

### 3. ESM Mocking with vi.hoisted()

**CRITICAL for ESM modules**:

```typescript
// ✅ Define mocks in hoisted context FIRST
const { mockFn } = vi.hoisted(() => ({
  mockFn: vi.fn()
}));

vi.mock('./module', () => ({
  myFunc: mockFn
}));

import { myFunc } from './module';
`

Validation Details

Front Matter
Required Fields
Valid Name Format
Valid Description
Has Sections
Allowed Tools
Instruction Length:
4645 chars