このチュートリアルで学ぶこと
✓ セットアップ
✓ 基本的なテストの書き方
✓ クエリの使い分け
✓ ユーザーイベント
✓ 非同期テスト
Step 1: セットアップ
npm install -D @testing-library/react @testing-library/jest-dom @testing-library/user-event jest jest-environment-jsdom
Step 2: 基本的なテスト
// Button.tsx
export function Button({ onClick, children }) {
return <button onClick={onClick}>{children}</button>;
}
// 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 correctly', () => {
render(<Button>Click me</Button>);
expect(screen.getByRole('button', { name: 'Click me' })).toBeInTheDocument();
});
it('calls onClick when clicked', async () => {
const handleClick = jest.fn();
render(<Button onClick={handleClick}>Click me</Button>);
await userEvent.click(screen.getByRole('button'));
expect(handleClick).toHaveBeenCalledTimes(1);
});
});
Step 3: クエリの使い分け
// 優先順位(アクセシビリティ重視)
screen.getByRole('button', { name: 'Submit' }); // 最優先
screen.getByLabelText('Email'); // フォーム要素
screen.getByPlaceholderText('Enter email'); // プレースホルダー
screen.getByText('Hello World'); // テキスト
screen.getByTestId('custom-element'); // 最終手段
// 存在確認
screen.queryByRole('button'); // なければnull
await screen.findByRole('button'); // 非同期で待つ
Step 4: フォームテスト
// LoginForm.test.tsx
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { LoginForm } from './LoginForm';
it('submits form with correct values', async () => {
const handleSubmit = jest.fn();
render(<LoginForm onSubmit={handleSubmit} />);
await userEvent.type(screen.getByLabelText('Email'), 'test@example.com');
await userEvent.type(screen.getByLabelText('Password'), 'password123');
await userEvent.click(screen.getByRole('button', { name: 'Login' }));
expect(handleSubmit).toHaveBeenCalledWith({
email: 'test@example.com',
password: 'password123'
});
});
Step 5: 非同期テスト
// UserList.test.tsx
import { render, screen, waitFor } from '@testing-library/react';
import { UserList } from './UserList';
it('displays users after loading', async () => {
render(<UserList />);
expect(screen.getByText('Loading...')).toBeInTheDocument();
await waitFor(() => {
expect(screen.getByText('Alice')).toBeInTheDocument();
});
expect(screen.queryByText('Loading...')).not.toBeInTheDocument();
});
Step 6: モック
// API モック
jest.mock('./api', () => ({
fetchUsers: jest.fn().mockResolvedValue([
{ id: 1, name: 'Alice' }
])
}));
// コンポーネントモック
jest.mock('./Header', () => ({
Header: () => <div data-testid="mock-header">Header</div>
}));
まとめ
React Testing Libraryはユーザー視点でテストを書くことを推奨します。アクセシビリティを意識したクエリでテストしましょう。
← 一覧に戻る