TypeScriptで型安全なテストコードを書く方法

先生

TypeScriptでテストコード書くとバグが減るってマジ!?型安全テストで開発効率爆上げ🚀

TypeScriptで型安全なテストコードを書くメリット

TypeScriptでテストコードを書く最大のメリットは、型安全性を担保できることです。JavaScriptと比較して、コンパイル時に型エラーを検出できるため、実行時のエラーを大幅に減らすことができます。

これにより、リファクタリング時の安全性も向上し、より自信を持ってコードを変更できるようになります。特に大規模なプロジェクトでは、型安全性の恩恵は非常に大きいです。

型定義をしっかりと行うことで、テストコード自体もドキュメントとしての役割を果たし、コードの意図を明確に伝えることができます。

JestとTypeScriptで始める型安全テスト

Jestは、Reactアプリケーションで広く使用されているテスティングフレームワークです。TypeScriptとの相性も良く、簡単に導入できます。

まず、必要なパッケージをインストールします。

npm install --save-dev jest ts-jest @types/jest typescript

次に、Jestの設定ファイルを作成します。

npx ts-jest config:init

これにより、jest.config.jsファイルが生成されます。このファイルで、TypeScriptの設定をJestに適用するための設定を行います。

例えば、以下のような設定になります。

module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
};

これで、TypeScriptで書かれたテストコードを実行できるようになりました。

具体的なテストコードの例

簡単な例として、加算を行う関数addをテストするコードを見てみましょう。

// src/add.ts
export function add(a: number, b: number): number {
  return a + b;
}
// test/add.test.ts
import { add } from '../src/add';

describe('add', () => {
  it('should return the sum of two numbers', () => {
    expect(add(1, 2)).toBe(3);
  });

  it('should return the sum of two negative numbers', () => {
    expect(add(-1, -2)).toBe(-3);
  });
});

この例では、describeブロックでテストケースをグループ化し、itブロックで個々のテストを定義しています。expect関数を使って、期待される結果と実際の結果を比較しています。

TypeScriptの型チェックにより、add関数に数値以外の引数を渡した場合、コンパイル時にエラーが発生します。これにより、型に関する問題を早期に発見できます。

モックと型

外部APIやデータベースとの連携など、依存関係がある関数のテストでは、モックを使用することが一般的です。TypeScriptでは、モックの型を定義することで、より安全なテストコードを書くことができます。

例えば、axiosを使って外部APIを呼び出す関数をテストする場合、axiosのモックを作成し、その型を定義します。

import axios from 'axios';

interface User {
  id: number;
  name: string;
}

export async function fetchUser(id: number): Promise<User> {
  const response = await axios.get<User>(https://example.com/users/${id});
  return response.data;
}
// test/fetchUser.test.ts
import { fetchUser } from '../src/fetchUser';
import axios from 'axios';

jest.mock('axios');
const mockedAxios = axios as jest.Mocked<typeof axios>;

describe('fetchUser', () => {
  it('should return a user', async () => {
    const mockUser: User = { id: 1, name: 'John Doe' };
    mockedAxios.get.mockResolvedValue({ data: mockUser });

    const user = await fetchUser(1);
    expect(user).toEqual(mockUser);
  });
});

この例では、jest.mock('axios')axiosをモックし、mockedAxios変数でモックされたaxiosに型を付与しています。これにより、モックのメソッドやプロパティに誤った値を設定した場合、TypeScriptがエラーを検出してくれます。

参考リンク

まとめ

TypeScriptで型安全なテストコードを書くことで、JavaScriptでテストを書くよりも多くのメリットが得られます。コンパイル時の型チェック、リファクタリングの安全性、コードのドキュメント化など、開発効率と品質を向上させることができます。Jestなどのテスティングフレームワークと組み合わせることで、より強力なテスト環境を構築できます。ぜひ、TypeScriptでテストコードを書いてみてください。