Skip to content
⚠️ This article was written in 2019. Some content may be outdated.

Jestフロントエンドユニットテスト実践ガイド

ユニットテストの価値はよく知られていますが、多くのフロントエンドプロジェクトでは導入のオーバーヘッドでスキップされています。本記事では完全なセットアップワークフローと実践的なテスト例を紹介し、実際のプロジェクトで遭遇するシナリオをカバーします。

インストールと設定

bash
npm install --save-dev jest babel-jest @babel/core @babel/preset-env
# Reactプロジェクトの場合、追加インストール:
npm install --save-dev @babel/preset-react @testing-library/react @testing-library/jest-dom
json
// package.json
{
  "scripts": {
    "test": "jest",
    "test:watch": "jest --watch",
    "test:coverage": "jest --coverage"
  },
  "jest": {
    "testEnvironment": "jsdom",
    "setupFilesAfterFramework": ["@testing-library/jest-dom/extend-expect"],
    "collectCoverageFrom": ["src/**/*.{js,jsx}", "!src/index.js"]
  }
}
javascript
// babel.config.js
module.exports = {
  presets: [
    ["@babel/preset-env", { targets: { node: "current" } }],
    "@babel/preset-react",
  ],
};

コアマッチャー

javascript
// math.js — テスト対象の関数
export const sum = (a, b) => a + b;
export const subtract = (a, b) => a - b;
export const multiply = (a, b) => a * b;
export const divide = (a, b) => {
  if (b === 0) throw new Error("ゼロで割ることはできません");
  return a / b;
};
javascript
// math.test.js
import { sum, subtract, multiply, divide } from "./math";

describe("数学ユーティリティ", () => {
  // 等値
  test("sum: 1 + 2 = 3", () => {
    expect(sum(1, 2)).toBe(3); // 厳密等価(===)
    expect(sum(1, 2)).toEqual(3); // 深い等価(オブジェクト・配列)
  });

  // 真偽値
  test("subtract: 結果は真偽値", () => {
    expect(subtract(5, 3)).toBeTruthy(); // 真値
    expect(subtract(3, 3)).toBeFalsy(); // 偽値
    expect(subtract(5, 3)).toBeDefined(); // undefinedでない
  });

  // 数値
  test("multiply: 2 * 3 = 6", () => {
    expect(multiply(2, 3)).toBe(6);
    expect(multiply(0.1, 0.2)).toBeCloseTo(0.02); // 浮動小数点比較
  });

  // 例外
  test("divide: ゼロ除算で例外をスロー", () => {
    expect(() => divide(10, 0)).toThrow("ゼロで割ることはできません");
    expect(() => divide(10, 0)).toThrow(Error);
  });

  // 配列とオブジェクト
  test("配列内の結果", () => {
    expect([1, 2, 3]).toContain(2);
    expect({ name: "アリス", age: 25 }).toMatchObject({ name: "アリス" });
  });
});

非同期テスト

javascript
// 非同期関数
test("非同期関数のテスト", async () => {
  const data = await fetchUser(1);
  expect(data.name).toBe("アリス");
});

// 非同期リクエストのモック
jest.mock("./api", () => ({
  fetchUser: jest.fn().mockResolvedValue({ id: 1, name: "アリス" }),
}));

最も重要な純粋関数ロジックから始めましょう——副作用のない関数が最もテストしやすく、最も高い費用対効果を提供します。

MIT Licensed