jest-generator について
JavaScript と TypeScript のプロジェクト向けに Jest のユニットテストを生成するスキルです。テスト構成、モック、React コンポーネントのテスト、カバレッジ確認を案内します。
主な機能
- 01Jest テストの生成
- 02ソースとテストの命名規則
- 03モックとスパイのパターン
- 04非同期処理とタイマーのテスト
- 05React コンポーネントのテスト例
- 06テスト品質チェックリスト
活用シーン
- 01JS・TS モジュールのテスト作成
- 02React コンポーネントのテスト
- 03既存コードへのカバレッジ追加
- 04非同期動作とエラー処理の確認
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ secondsky/ claude-skills --skill jest-generatorインストール後、Claude Code で/jest-generatorを入力して読み込まれたか確認します。
詳細
Jest ジェネレータースキル
目的
Jest の規約とベストプラクティスに従い、適切なモック、describe ブロック、コード構成を用いて、JavaScript および TypeScript のコード向けに Jest ベースの単体テストを生成します。
使用する場面
- JavaScript/TypeScript のモジュール向けに Jest テストを生成する
- React コンポーネントのテストファイルを作成する
- 既存のコードに不足しているテストカバレッジを追加する
- モック、スパイ、スナップショットなど、Jest 固有のパターンが必要な場合
テストファイルの命名
ソースとテストの対応関係:
src/components/Feature.tsx→src/components/Feature.test.tsxsrc/utils/validator.ts→src/utils/validator.test.tssrc/models/User.ts→src/models/User.test.ts
テストの実行
# Preferred: Using bun (faster)
bun test
# Run specific file
bun test src/utils/validator.test.ts
# Run with coverage
bun test --coverage
# Watch mode
bun test --watch
# Alternative: Using npm
npm test
npm test -- --coverage
Jest テストの構成
import { functionToTest, ClassToTest } from './Feature'
jest.mock('./dependency')
describe('ModuleName', () => {
beforeEach(() => {
jest.clearAllMocks()
})
afterEach(() => {
jest.restoreAllMocks()
})
describe('ClassName', () => {
let instance: ClassToTest
beforeEach(() => {
instance = new ClassToTest()
})
it('should return expected result with valid input', () => {
// Arrange
const input = { key: 'value' }
const expected = { processed: true }
// Act
const result = instance.method(input)
// Assert
expect(result).toEqual(expected)
})
it('should throw error with invalid input', () => {
expect(() => instance.method(null)).toThrow('Invalid input')
})
})
})
Jest 固有のパターン
モック
// Mock entire module
jest.mock('./api', () => ({
fetchData: jest.fn(),
}))
// Mock with implementation
const mockFn = jest.fn((x: number) => x * 2)
// Spy on method
const spy = jest.spyOn(obj, 'method').mockReturnValue('mocked')
spy.mockRestore()
非同期テスト
it('should resolve with data', async () => {
const result = await asyncFunction()
expect(result).toBeDefined()
})
it('should reject with error', async () => {
await expect(asyncFunction()).rejects.toThrow('Error')
})
タイマー
beforeEach(() => jest.useFakeTimers())
afterEach(() => jest.useRealTimers())
it('should execute after timeout', () => {
const callback = jest.fn()
setTimeout(callback, 1000)
jest.advanceTimersByTime(1000)
expect(callback).toHaveBeenCalled()
})
一般的なマッチャー
// Equality
expect(value).toBe(expected)
expect(value).toEqual(expected)
// Truthiness
expect(value).toBeTruthy()
expect(value).toBeNull()
expect(value).toBeDefined()
// Arrays/Objects
expect(array).toContain(item)
expect(obj).toHaveProperty('key')
// Functions/Promises
expect(fn).toThrow('error')
await expect(promise).resolves.toBe(value)
// Mock functions
expect(mockFn).toHaveBeenCalled()
expect(mockFn).toHaveBeenCalledWith(arg)
React コンポーネントのテスト
import { render, screen, fireEvent } from '@testing-library/react'
import '@testing-library/jest-dom'
import { Button } from './Button'
describe('Button', () => {
it('should call onClick when clicked', () => {
const handleClick = jest.fn()
render(<Button onClick={handleClick}>Click me</Button>)
fireEvent.click(screen.getByText('Click me'))
expect(handleClick).toHaveBeenCalledTimes(1)
})
})
品質チェックリスト
- テストファイルに適切な名前が付いている(
<module>.test.ts) - エクスポートされているすべての関数/クラスをテストしている
- 正常系とエッジケースを含めている
- エラー条件をテストしている
- 外部依存関係をモックしている
- describe ブロックでテストを整理している
- セットアップ/クリーンアップに beforeEach/afterEach を使用している
- わかりやすいテスト名を付けている
- カバレッジが 80% 以上である
ベストプラクティス
- わかりやすいテスト名を使います:
should <expected> when <condition> - describe ブロックで整理します
- 外部依存関係のみをモックします
- コンポーネントではユーザーの操作をテストします
- パラメーター化テストには test.each を使います
- テストを独立させます
- エラー条件をテストします
- カバレッジ 80% 以上を目指します
コメント
Markdown 対応