一键导入
jest
Unit, integration, and snapshot testing with Jest. Trigger: When writing or running tests with Jest.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Unit, integration, and snapshot testing with Jest. Trigger: When writing or running tests with Jest.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Paste-ready session summary for context transfer to a new chat. Trigger: User says 'context handoff', 'start fresh', or session needs to continue.
One-at-a-time questioning to fully profile a goal before acting. Trigger: User says 'grill me', goal is vague, or clarification is needed first.
Batch execution with checkpoints. Trigger: When executing plans with batched tasks.
Universal coding principles: DRY, security by default, null guards, and YAGNI. Trigger: When writing or reviewing code in any language or technology.
Accessibility guide (WCAG 2.1/2.2, Level A–AAA). Trigger: When building UI components, interactive elements, or auditing accessibility compliance.
Astro quality patterns: island philosophy, SEO by page type, and Core Web Vitals. Trigger: When reviewing Astro site quality or hydration decisions.
| name | jest |
| description | Unit, integration, and snapshot testing with Jest. Trigger: When writing or running tests with Jest. |
| license | Apache 2.0 |
| metadata | {"version":"1.1","type":"tooling","skills":["unit-testing"],"dependencies":{"jest":">=29.0.0 <30.0.0"}} |
Standard test runner for JS/TS projects with built-in mocking, assertions, and coverage.
Don't use for:
Group related tests with describe; name individual cases with it.
// CORRECT: grouped, descriptive names
describe('UserService', () => {
it('should return created user with an id', async () => {
const user = await service.createUser({ name: 'Ada' });
expect(user.id).toBeDefined();
});
});
// WRONG: flat, vague names
test('test1', () => { /* ... */ });
// CORRECT: fresh instance per test
let service: UserService;
beforeEach(() => { service = new UserService(mockRepo); });
afterEach(() => { jest.restoreAllMocks(); });
// WRONG: shared mutable state across tests
const service = new UserService(mockRepo);
// jest.mock: replace entire module
jest.mock('../repositories/userRepo');
const mockRepo = jest.mocked(userRepo);
mockRepo.save.mockResolvedValue({ id: '1', name: 'Ada' });
// jest.spyOn: spy on one method, keep the rest real
const spy = jest.spyOn(logger, 'warn').mockImplementation();
expect(spy).toHaveBeenCalledWith('Empty input');
// CORRECT: awaited rejects matcher
it('should reject on failure', async () => {
mockFetch.mockRejectedValue(new Error('timeout'));
await expect(service.fetchData()).rejects.toThrow('timeout');
});
// WRONG: missing await causes silent pass
it('silent', () => { expect(service.fetchData()).rejects.toThrow(); });
Jest matchers cover both sides: what MUST be true (positive) and what MUST NOT be true (negative). This is the API layer — see unit-testing skill for the philosophy of when to write each.
// ── Positive matchers (value, shape, behavior) ──
expect(user.id).toBeDefined();
expect(user.role).toBe('member');
expect(users).toContain(newUser);
expect(mockRepo.save).toHaveBeenCalledWith(expect.objectContaining({ name: 'Ada' }));
// ── Negative matchers (.not modifier) ──
expect(result.errors).not.toContain('email');
expect(spy).not.toHaveBeenCalled();
// ── Throw / reject matchers ──
expect(() => parse(null)).toThrow('Input required');
expect(() => parse(null)).toThrow(TypeError);
await expect(service.fetch('bad-id')).rejects.toThrow('Not found');
await expect(service.fetch('bad-id')).rejects.toBeInstanceOf(NotFoundError);
New test file?
→ name it module.test.ts next to source
Replace a whole module?
→ jest.mock('./path')
Spy on one method?
→ jest.spyOn(object, 'method')
Async code?
→ async/await in the it callback
Error paths?
→ await expect(...).rejects.toThrow()
Shared setup?
→ beforeEach + afterEach cleanup
import { OrderService } from './orderService';
import { paymentGateway } from '../gateways/paymentGateway';
import { orderRepo } from '../repositories/orderRepo';
jest.mock('../gateways/paymentGateway');
jest.mock('../repositories/orderRepo');
const mockPay = jest.mocked(paymentGateway);
const mockRepo = jest.mocked(orderRepo);
describe('OrderService.placeOrder', () => {
beforeEach(() => { jest.resetAllMocks(); });
it('should charge and save', async () => {
mockPay.charge.mockResolvedValue({ status: 'ok' });
mockRepo.save.mockResolvedValue({ id: '42', total: 100 });
const order = await new OrderService().placeOrder({ items: ['A'], total: 100 });
expect(mockPay.charge).toHaveBeenCalledWith(100);
expect(order.id).toBe('42');
});
});
jest.unstable_mockModule for ESM; jest.mock is CommonJS onlyawait assertions; use jest.useFakeTimers() for time-dependent logic--updateSnapshot intentionallyjest.useRealTimers() in afterEach to prevent bleedjest.resetModules() if module caches state at importdescribe groups a single unit (class, function, or module)it tests one behavior with a descriptive namebeforeEach resets state; afterEach restores mocksasync/awaitjest.config.ts