一键导入
unit-test
Unit tests with Jest + React Testing Library. CRITICAL - Uses Jest (NOT Vitest).
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Unit tests with Jest + React Testing Library. CRITICAL - Uses Jest (NOT Vitest).
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Create robust, error-proof Prisma seed scripts with comprehensive error handling and validation.
Create Next.js 16 API Route Handlers. Use when building REST endpoints (GET, POST, PUT, DELETE), implementing CRUD operations, or creating authenticated APIs with Zod validation.
Create React/Next.js 16 components. Use when building pages, client/server components, forms with useActionState, or UI with shadcn/ui. ALWAYS activate with frontend-design together.
Write integration tests with Jest for API routes and database operations. Use when testing backend logic, API endpoints, or data layer.
Review code for quality, security, performance, and best practices. Use when reviewing changes before commit, auditing code for issues, or suggesting improvements.
Debug code errors systematically. Use when analyzing error messages, fixing bugs, resolving build/lint errors, or troubleshooting runtime issues.
| name | unit-test |
| description | Unit tests with Jest + React Testing Library. CRITICAL - Uses Jest (NOT Vitest). |
// Jest globals (no import needed)
jest.fn(), jest.mock(), jest.clearAllMocks()
// Vitest (will fail!)
import { vi } from 'vitest' // ERROR!
| Component Type | Max Tests | Focus |
|---|---|---|
| Static (no fetch) | 1 | Renders with props |
| Async (with fetch) | 2 | Heading + loaded data |
it('renders correctly', async () => {
// Multiple expects in ONE test = good
expect(heading).toBeInTheDocument();
expect(item1).toBeInTheDocument();
expect(item2).toBeInTheDocument();
});
import { render, screen, waitFor, act } from '@testing-library/react';
import { MySection } from '@/components/home/MySection';
// Suppress Next.js Image warnings
const originalError = console.error;
beforeAll(() => {
console.error = (...args: any[]) => {
if (args[0]?.includes?.('React does not recognize')) return;
if (args[0]?.includes?.('received `true` for a non-boolean')) return;
originalError(...args);
};
});
afterAll(() => {
console.error = originalError;
});
describe('MySection', () => {
beforeEach(() => {
jest.clearAllMocks();
global.fetch = jest.fn().mockResolvedValue({
ok: true,
json: () => Promise.resolve({
success: true,
data: [
{ id: '1', title: 'Item 1', author: 'Author 1' },
{ id: '2', title: 'Item 2', author: 'Author 2' },
],
}),
});
});
afterEach(() => {
jest.restoreAllMocks();
});
// TEST 1: Renders section correctly (REQUIRED)
it('renders section with heading and content', async () => {
await act(async () => {
render(<MySection />);
});
// Static content (heading)
expect(screen.getByRole('heading', { name: /my section/i })).toBeInTheDocument();
// Dynamic content (after fetch)
await waitFor(() => {
expect(screen.getByText(/item 1/i)).toBeInTheDocument();
});
expect(screen.getByText(/item 2/i)).toBeInTheDocument();
});
// TEST 2: Links/interactions (OPTIONAL - only if component has links)
it('renders navigation link', async () => {
await act(async () => {
render(<MySection />);
});
const link = screen.getByRole('link', { name: /view all/i });
expect(link.getAttribute('href')).toContain('/items');
});
});
// DONE! 2 tests = complete coverage for this component
act() + waitFor()await act(async () => { render(<Component />); });
await waitFor(() => { expect(screen.getByText(/data/i)).toBeInTheDocument(); });
getAllByText() or getByRole()// Text appears multiple times
const elements = screen.getAllByText(/science/i);
expect(elements.length).toBeGreaterThan(0);
// Be specific with role
expect(screen.getByRole('heading', { name: /science/i })).toBeInTheDocument();
/i flagscreen.getByText(/featured books/i); //
screen.getByText('Featured Books'); // ❌
expect(link.getAttribute('href')).toContain('/books'); //
expect(link).toHaveAttribute('href', '/books'); // ❌
// Read source code first
expect(screen.getByRole('heading')).toBeInTheDocument();
// Don't assume elements exist
expect(screen.getByPlaceholderText(/search/i)).toBeInTheDocument(); // May not exist!
beforeEach(() => {
global.fetch = jest.fn().mockResolvedValue({
ok: true,
json: () => Promise.resolve({ success: true, data: [...] }),
});
});
| Priority | Query | Use Case |
|---|---|---|
| 1 | getByRole | Buttons, links, headings |
| 2 | getByText | Static text (use /i) |
| 3 | getAllByText | Text appears multiple times |
| Don't | Why |
|---|---|
| 5+ tests per component | Too many failure points |
| Test empty/error states | Component may not have them |
| Test loading skeletons | Data loads sync in Jest |
| Separate test per element | Combine in one test |
import { vi } from 'vitest' | Use Jest, not Vitest |