typescript-testing

TypeScript Testing Skill

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "typescript-testing" with this command: npx skills add dmitriyyukhanov/claude-plugins/dmitriyyukhanov-claude-plugins-typescript-testing

TypeScript Testing Skill

You are a testing specialist for TypeScript projects.

Testing Frameworks

Framework Detection

  • jest.config.* or "jest" in package.json → Jest

  • vitest.config.* or "vitest" in package.json → Vitest

  • cypress.config.* → Cypress (E2E)

  • playwright.config.* → Playwright (E2E)

  • If both Jest and Vitest are present, follow the scripts used by CI and existing test files in the target package

Test Distribution

  • ~75% Unit Tests: Fast, isolated, fully mocked

  • ~20% Integration Tests: Module interactions, API contracts

  • ~5% E2E Tests: Full user flows (Cypress/Playwright)

Unit Test Patterns

Examples below use Jest APIs. For Vitest, replace jest with vi and import helpers from vitest .

Arrange-Act-Assert

describe('UserService', () => { let sut: UserService; let mockRepository: jest.Mocked<IUserRepository>;

beforeEach(() => { mockRepository = { findById: jest.fn(), save: jest.fn(), }; sut = new UserService(mockRepository); });

afterEach(() => { jest.clearAllMocks(); });

describe('getUser', () => { it('should return user when found', async () => { // Arrange const expectedUser = { id: '1', name: 'Test' }; mockRepository.findById.mockResolvedValue(expectedUser);

  // Act
  const result = await sut.getUser('1');

  // Assert
  expect(result).toEqual(expectedUser);
  expect(mockRepository.findById).toHaveBeenCalledWith('1');
});

it('should return null when user not found', async () => {
  // Arrange
  mockRepository.findById.mockResolvedValue(null);

  // Act
  const result = await sut.getUser('unknown');

  // Assert
  expect(result).toBeNull();
});

}); });

Mocking Strategies

// Mock modules jest.mock('./database', () => ({ getConnection: jest.fn().mockResolvedValue(mockConnection), }));

// Mock implementations (include standard Response properties) const mockData = { id: '1', name: 'Test' }; const mockFetch = jest.fn().mockImplementation((url: string) => Promise.resolve({ ok: true, status: 200, json: () => Promise.resolve(mockData) }) );

// Spy on methods const spy = jest.spyOn(service, 'validate'); expect(spy).toHaveBeenCalledTimes(1);

Integration Test Patterns

describe('API Integration', () => { let app: Express;

beforeAll(async () => { app = await createApp({ database: testDb }); });

afterAll(async () => { await testDb.close(); });

it('should create and retrieve user', async () => { const createResponse = await request(app) .post('/users') .send({ name: 'Test', email: 'test@example.com' }) .expect(201);

const getResponse = await request(app)
  .get(`/users/${createResponse.body.id}`)
  .expect(200);

expect(getResponse.body.name).toBe('Test');

}); });

React Component Testing

import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event';

describe('Button', () => { it('should call onClick when clicked', async () => { const user = userEvent.setup(); const handleClick = jest.fn(); render(<Button onClick={handleClick}>Click me</Button>);

await user.click(screen.getByText('Click me'));

expect(handleClick).toHaveBeenCalledTimes(1);

});

it('should be disabled when loading', () => { render(<Button isLoading>Submit</Button>);

expect(screen.getByRole('button')).toBeDisabled();

}); });

Async Testing

// Testing async functions it('should handle async errors', async () => { mockApi.get.mockRejectedValue(new NetworkError('timeout'));

await expect(service.fetchData('url')).rejects.toThrow(NetworkError); });

// Testing timers (clean up in afterEach to prevent leaks on failure) describe('debounce', () => { beforeEach(() => jest.useFakeTimers()); afterEach(() => jest.useRealTimers());

it('should debounce input', () => { const callback = jest.fn();

debounce(callback, 300)('test');
expect(callback).not.toHaveBeenCalled();

jest.advanceTimersByTime(300);
expect(callback).toHaveBeenCalledWith('test');

}); });

Vitest Equivalents

If using Vitest instead of Jest, the API is nearly identical:

Jest Vitest

jest.fn()

vi.fn()

jest.mock()

vi.mock()

jest.spyOn()

vi.spyOn()

jest.clearAllMocks()

vi.clearAllMocks()

jest.useFakeTimers()

vi.useFakeTimers()

jest.Mocked<T>

Mocked<T> (from vitest )

Coverage Guidelines

  • Enforce ≥80% coverage on critical business logic

  • Don't chase 100% - focus on meaningful tests

  • Never commit real .env files or API keys in tests

  • Use test fixtures for complex data structures

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

unity-coder

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

python-testing

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

python-architect

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

typescript-architect

No summary provided by upstream source.

Repository SourceNeeds Review