関連記事:JavaScript入門ガイド
Jestは、Meta(旧Facebook)が開発したJavaScriptのテスティングフレームワークです。設定不要で始められ、JavaScript/TypeScriptプロジェクトで最も広く使われています。
なぜテストを書くのか
- バグを早期発見できる
- リファクタリングを安心して行える
- コードの仕様書として機能する
- チーム開発での品質担保になる
セットアップ
npm install -D jest
package.json にテストスクリプトを追加します。
{
"scripts": {
"test": "jest",
"test:watch": "jest --watch"
}
}
基本的なテストの書き方
テスト対象の関数:
// math.js
function add(a, b) {
return a + b;
}
function divide(a, b) {
if (b === 0) throw new Error('0で割ることはできません');
return a / b;
}
module.exports = { add, divide };
テストコード:
// math.test.js
const { add, divide } = require('./math');
describe('add関数', () => {
test('2 + 3 は 5 になる', () => {
expect(add(2, 3)).toBe(5);
});
test('負の数も正しく計算できる', () => {
expect(add(-1, -2)).toBe(-3);
});
});
describe('divide関数', () => {
test('10 / 2 は 5 になる', () => {
expect(divide(10, 2)).toBe(5);
});
test('0で割るとエラーが発生する', () => {
expect(() => divide(10, 0)).toThrow('0で割ることはできません');
});
});
よく使うマッチャー
| マッチャー | 用途 |
|---|---|
toBe(value) | 厳密等価(===) |
toEqual(value) | オブジェクトの深い比較 |
toBeTruthy() | truthyな値 |
toContain(item) | 配列に含まれるか |
toThrow() | 例外が投げられるか |
toHaveLength(n) | 配列・文字列の長さ |
モック(Mock)
外部依存を置き換えてテストします。
// API呼び出しのモック
const fetchUser = jest.fn();
fetchUser.mockResolvedValue({ id: 1, name: 'テスト太郎' });
test('ユーザー情報を取得できる', async () => {
const user = await fetchUser(1);
expect(user.name).toBe('テスト太郎');
expect(fetchUser).toHaveBeenCalledWith(1);
});
モジュールのモック
jest.mock('./api');
const { getUser } = require('./api');
getUser.mockResolvedValue({ id: 1, name: 'テスト' });
非同期テスト
// async/await
test('非同期でデータを取得できる', async () => {
const data = await fetchData();
expect(data).toEqual({ status: 'ok' });
});
// Promise
test('Promiseが正しく解決される', () => {
return expect(fetchData()).resolves.toEqual({ status: 'ok' });
});
Reactコンポーネントのテスト
React Testing Libraryと組み合わせます。
npm install -D @testing-library/react @testing-library/jest-dom
import { render, screen, fireEvent } from '@testing-library/react';
import Counter from './Counter';
test('カウンターが正しく動作する', () => {
render(<Counter />);
expect(screen.getByText('カウント: 0')).toBeInTheDocument();
fireEvent.click(screen.getByText('+1'));
expect(screen.getByText('カウント: 1')).toBeInTheDocument();
});
テストのベストプラクティス
- テスト名は日本語で具体的に書く
- Arrange-Act-Assertパターンに従う
- 1つのテストで1つのことだけ検証する
- 実装の詳細ではなく振る舞いをテストする
- テストが通らない場合はテスト自体を疑う前にコードを疑う
きれいなコードの書き方入門も参考にしてください。
まとめ
テストは書き始めるまでのハードルが高く感じますが、一度覚えれば開発の効率と安心感が大幅に上がります。まずは純粋な関数のテストから始めて、徐々にコンポーネントテストに広げていきましょう。