typescript-testing
Comprehensive testing guidance for TypeScript projects including unit testing patterns, mocking strategies, and test organization best practices
Best use case
typescript-testing is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Comprehensive testing guidance for TypeScript projects including unit testing patterns, mocking strategies, and test organization best practices
Teams using typescript-testing should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/typescript-testing/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How typescript-testing Compares
| Feature / Agent | typescript-testing | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Comprehensive testing guidance for TypeScript projects including unit testing patterns, mocking strategies, and test organization best practices
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
Related Guides
SKILL.md Source
# TypeScript Testing
Guidance for writing effective tests in TypeScript projects using Vitest or Jest.
## Rules
- **Arrange-Act-Assert**: Structure tests with clear setup, execution, and verification phases
- **Single Assertion Focus**: Each test should verify one specific behavior
- **Descriptive Names**: Use `describe` blocks for grouping and `it`/`test` with clear descriptions
- **Test Isolation**: Tests must not depend on execution order or shared mutable state
- **Mock External Dependencies**: Always mock I/O, network calls, and system interactions
- **Coverage Targets**: Aim for 80%+ line coverage, 70%+ branch coverage
- **No Logic in Tests**: Avoid conditionals and loops in test code
- **Clean Up**: Use `beforeEach`/`afterEach` for setup/teardown, never leave test artifacts
## Patterns
### Test Structure
```typescript
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
import { MyService } from "./my-service.js";
describe("MyService", () => {
let service: MyService;
beforeEach(() => {
service = new MyService();
vi.useFakeTimers();
});
afterEach(() => {
vi.useRealTimers();
vi.restoreAllMocks();
});
describe("methodName", () => {
it("should return expected result when given valid input", () => {
// Arrange
const input = "test";
// Act
const result = service.methodName(input);
// Assert
expect(result).toBe("expected");
});
it("should throw error when given invalid input", () => {
expect(() => service.methodName(null)).toThrow("Invalid input");
});
});
});
```markdown
### Mocking Dependencies
```typescript
import { vi, type Mock } from "vitest";
import type { Database } from "./database.js";
// Factory mock
vi.mock("./database.js", () => ({
Database: vi.fn().mockImplementation(() => ({
query: vi.fn(),
close: vi.fn(),
})),
}));
// Inline mock with type safety
const mockFetch = vi.fn() as Mock<typeof fetch>;
vi.stubGlobal("fetch", mockFetch);
mockFetch.mockResolvedValue(
new Response(JSON.stringify({ data: "test" }), {
status: 200,
headers: { "Content-Type": "application/json" },
})
);
```markdown
### Testing Async Code
```typescript
it("should handle async operations", async () => {
const promise = service.asyncMethod();
// Advance timers if needed
await vi.runAllTimersAsync();
const result = await promise;
expect(result).toBeDefined();
});
it("should reject with error on failure", async () => {
mockDependency.mockRejectedValueOnce(new Error("Network error"));
await expect(service.asyncMethod()).rejects.toThrow("Network error");
});
```markdown
### Snapshot Testing
```typescript
it("should match snapshot for complex output", () => {
const result = service.generateConfig();
expect(result).toMatchSnapshot();
});
it("should match inline snapshot", () => {
const result = service.formatOutput({ key: "value" });
expect(result).toMatchInlineSnapshot(`"{ key: 'value' }"`);
});
```markdown
## Anti-Patterns
```typescript
// ❌ Testing implementation details
it("should call internal method", () => {
const spy = vi.spyOn(service, "_privateMethod");
service.publicMethod();
expect(spy).toHaveBeenCalled(); // Don't test internals
});
// ❌ Multiple unrelated assertions
it("should work", () => {
expect(service.method1()).toBe("a");
expect(service.method2()).toBe("b");
expect(service.method3()).toBe("c"); // Split into separate tests
});
// ❌ Test interdependence
let sharedState: string;
it("first test", () => { sharedState = "set"; });
it("depends on first", () => { expect(sharedState).toBe("set"); }); // Never do this
// ❌ Not awaiting async code
it("broken async test", () => {
service.asyncMethod().then(r => expect(r).toBe("x")); // Missing await/return
});
// ❌ Overspecified mocks
mockFn.mockReturnValueOnce("a")
.mockReturnValueOnce("b")
.mockReturnValueOnce("c"); // Fragile, breaks if call order changes
```markdown
## Examples
### Testing a Service Class
```typescript
import { describe, it, expect, vi, beforeEach } from "vitest";
import { UserService } from "./user-service.js";
import type { UserRepository } from "./user-repository.js";
describe("UserService", () => {
let service: UserService;
let mockRepo: UserRepository;
beforeEach(() => {
mockRepo = {
findById: vi.fn(),
save: vi.fn(),
delete: vi.fn(),
};
service = new UserService(mockRepo);
});
describe("getUser", () => {
it("should return user when found", async () => {
const user = { id: "1", name: "Test" };
vi.mocked(mockRepo.findById).mockResolvedValue(user);
const result = await service.getUser("1");
expect(result).toEqual(user);
expect(mockRepo.findById).toHaveBeenCalledWith("1");
});
it("should return null when user not found", async () => {
vi.mocked(mockRepo.findById).mockResolvedValue(null);
const result = await service.getUser("999");
expect(result).toBeNull();
});
});
});
```markdown
### Testing Error Handling
```typescript
describe("error handling", () => {
it("should wrap repository errors", async () => {
const dbError = new Error("Connection failed");
vi.mocked(mockRepo.findById).mockRejectedValue(dbError);
await expect(service.getUser("1")).rejects.toThrow("Failed to fetch user");
});
it("should handle validation errors gracefully", () => {
expect(() => service.validateInput("")).toThrow(ValidationError);
expect(() => service.validateInput("")).toThrow("Input cannot be empty");
});
});
```
## References
- [Vitest Documentation](https://vitest.dev/)
- [Jest Documentation](https://jestjs.io/)
- [Testing Library](https://testing-library.com/)
- [MSW (Mock Service Worker)](https://mswjs.io/)Related Skills
typescript-strict
TypeScript strict mode patterns. Use when writing any TypeScript code.
typescript-sdk-specialist
TypeScript SDK development with Node.js and browser support. Design SDK architecture, implement type-safe API clients, support ESM and CommonJS modules, and configure bundling for browsers.
typescript-pro
Expert TypeScript developer specializing in advanced type system features, generic programming, and type-safe application architecture. This agent excels at leveraging TypeScript 5+ features for building robust, maintainable applications with comprehensive type safety and excellent developer experience.
typescript-nestjs-best-practices-cursorrules-promp-cursorrules
Apply for typescript-nestjs-best-practices-cursorrules-promp. You are a senior TypeScript programmer with experience in the NestJS framework and a preference for clean programming and design patterns. Generate code, corrections, and refactorings that comply with
typescript-hook-writer
Expert guidance for developing Claude Code hooks in TypeScript with shared utilities, esbuild compilation, and Vitest testing - distributes compiled JS while maintaining TypeScript development experience
typescript-esm-utils-developer-maintainer
skill for developing and maintaining TypeScript utility libraries transpiled to esm. Use this skill when working on TypeScript projects that involve creating reusable utility functions, managing library structure, testing, documentation, and build processes. This includes creating new utilities, refactoring existing code, setting up testing frameworks, configuring build tools, and ensuring type safety.
typescript-docs
Generates comprehensive TypeScript documentation using JSDoc, TypeDoc, and multi-layered documentation patterns for different audiences. Use when creating API documentation, architectural decision records (ADRs), code examples, and framework-specific patterns for NestJS, Express, React, Angular, and Vue.
typescript-developer
Use when developing applications or components using TypeScript, ensuring type safety and leveraging TypeScript features.
typescript-advanced-types
Master TypeScript's advanced type system including generics, conditional types, mapped types, template literals, and utility types for building type-safe applications. Use when implementing complex...
tip-javascript-typescript
This skill should be used when writing or refactoring TypeScript/JavaScript code. It provides coding patterns and best practices aligned with the user's preferred development style, typescript language usage patterns, and library-specific tips.
testing-tauri-apps
Guides developers through testing Tauri applications including unit testing with mock runtime, mocking Tauri APIs, WebDriver end-to-end testing with Selenium and WebdriverIO, and CI integration with GitHub Actions.
testing-strategy-python
Python/FastAPI/Django testing conventions. pytest, fixtures, httpx, TestClient, factory_boy. Use when writing or reviewing Python tests.