원클릭으로
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 |