← スキル一覧に戻る

react-testing
by fusengine
Redefining development through cognitive automation and collaborative agent systems.
⭐ 0🍴 0📅 2026年1月24日
SKILL.md
name: react-testing description: Testing Library for React - render, screen, userEvent, waitFor. Use when writing tests for React components with Vitest or Jest. user-invocable: false
React Testing Library
Test React components the way users interact with them.
Installation
bun add -D @testing-library/react @testing-library/user-event @testing-library/jest-dom vitest jsdom
Vitest Configuration
// vite.config.ts
import { defineConfig } from 'vitest/config'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
test: {
environment: 'jsdom',
globals: true,
setupFiles: './src/test/setup.ts',
},
})
// src/test/setup.ts
import '@testing-library/jest-dom/vitest'
Basic Testing
// src/components/__tests__/Button.test.tsx
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { Button } from '../Button'
describe('Button', () => {
it('renders with text', () => {
render(<Button>Click me</Button>)
expect(screen.getByRole('button', { name: /click me/i })).toBeInTheDocument()
})
it('calls onClick when clicked', async () => {
const handleClick = vi.fn()
render(<Button onClick={handleClick}>Click me</Button>)
await userEvent.click(screen.getByRole('button'))
expect(handleClick).toHaveBeenCalledTimes(1)
})
it('is disabled when disabled prop is true', () => {
render(<Button disabled>Click me</Button>)
expect(screen.getByRole('button')).toBeDisabled()
})
})
Queries
Priority Order (Recommended)
- getByRole - Most accessible
- getByLabelText - Form inputs
- getByPlaceholderText - Inputs
- getByText - Text content
- getByTestId - Last resort
// Accessible queries
screen.getByRole('button', { name: /submit/i })
screen.getByRole('textbox', { name: /email/i })
screen.getByRole('heading', { level: 1 })
screen.getByLabelText(/password/i)
// Text queries
screen.getByText(/welcome/i)
screen.getByPlaceholderText(/search/i)
// Test ID (avoid if possible)
screen.getByTestId('custom-element')
Query Variants
// getBy - Throws if not found (sync)
screen.getByRole('button')
// queryBy - Returns null if not found (sync)
screen.queryByRole('button')
// findBy - Returns promise (async)
await screen.findByRole('button')
// getAllBy, queryAllBy, findAllBy - Multiple elements
screen.getAllByRole('listitem')
User Events
import userEvent from '@testing-library/user-event'
describe('Form', () => {
it('submits form data', async () => {
const user = userEvent.setup()
const handleSubmit = vi.fn()
render(<LoginForm onSubmit={handleSubmit} />)
// Type in inputs
await user.type(screen.getByLabelText(/email/i), 'test@example.com')
await user.type(screen.getByLabelText(/password/i), 'password123')
// Click submit
await user.click(screen.getByRole('button', { name: /login/i }))
expect(handleSubmit).toHaveBeenCalledWith({
email: 'test@example.com',
password: 'password123',
})
})
it('shows error on invalid input', async () => {
const user = userEvent.setup()
render(<LoginForm />)
await user.type(screen.getByLabelText(/email/i), 'invalid')
await user.click(screen.getByRole('button', { name: /login/i }))
expect(await screen.findByText(/invalid email/i)).toBeInTheDocument()
})
})
Async Testing
import { render, screen, waitFor } from '@testing-library/react'
describe('UserProfile', () => {
it('loads and displays user data', async () => {
render(<UserProfile userId="1" />)
// Wait for loading to finish
expect(screen.getByText(/loading/i)).toBeInTheDocument()
// Wait for data
await waitFor(() => {
expect(screen.getByText('John Doe')).toBeInTheDocument()
})
})
it('shows error on failure', async () => {
server.use(
http.get('/api/users/:id', () => {
return HttpResponse.error()
})
)
render(<UserProfile userId="1" />)
expect(await screen.findByText(/error loading/i)).toBeInTheDocument()
})
})
Mocking
Mock Functions
const mockFn = vi.fn()
mockFn.mockReturnValue('value')
mockFn.mockResolvedValue('async value')
mockFn.mockImplementation((x) => x * 2)
Mock Modules
vi.mock('../services/api', () => ({
fetchUser: vi.fn().mockResolvedValue({ name: 'John' }),
}))
MSW for API Mocking
// src/test/mocks/handlers.ts
import { http, HttpResponse } from 'msw'
export const handlers = [
http.get('/api/users/:id', ({ params }) => {
return HttpResponse.json({ id: params.id, name: 'John' })
}),
]
Best Practices
- Query by role - Most accessible and robust
- Use userEvent - More realistic than fireEvent
- Avoid implementation details - Test behavior, not internals
- Use async utilities - waitFor, findBy for async
- Mock at network level - Use MSW for API mocking
- Write descriptive test names - Clear intent
スコア
総合スコア
60/100
リポジトリの品質指標に基づく評価
✓SKILL.md
SKILL.mdファイルが含まれている
+20
✓LICENSE
ライセンスが設定されている
+10
○説明文
100文字以上の説明がある
0/10
○人気
GitHub Stars 100以上
0/15
○最近の活動
3ヶ月以内に更新がある
0/10
○フォーク
10回以上フォークされている
0/5
✓Issue管理
オープンIssueが50未満
+5
✓言語
プログラミング言語が設定されている
+5
○タグ
1つ以上のタグが設定されている
0/5
レビュー
💬
レビュー機能は近日公開予定です