🎭
jest-mock-extendedで型安全なモックを簡単に作成する
結論
jest-mock-extendedを使用することで、TypeScriptの型情報を活かした安全なモックを簡単に作成できます。インターフェースから型安全なモックを自動生成してくれるため、実装の詳細を知らなくてもテストに必要なモックを簡単に作成できます。
import { mock } from 'jest-mock-extended';
interface Mailer {
submitEmail: (email: string) => Promise<void>;
}
const mockMailer = mock<Mailer>();
mockMailer.submitEmail.mockResolvedValue();
詳細な使い方
基本的な機能
jest-mock-extendedには以下のような特徴があります:
- 型安全性
- インターフェースの完全な型チェック
- 引数の型チェック
- 戻り値の型チェック
- 使いやすさ
- オブジェクトやインターフェースを簡単にモック化
- Jestライクな親しみやすいAPI
実践的な使用例
インターフェースのモック
interface UserRepository {
findById: (id: string) => Promise<User>;
save: (user: User) => Promise<void>;
}
describe('UserService', () => {
const mockRepo = mock<UserRepository>();
test('should find user by id', async () => {
const mockUser = { id: '1', name: 'test' };
mockRepo.findById.mockResolvedValue(mockUser);
const user = await mockRepo.findById('1');
expect(user).toEqual(mockUser);
});
});
引数の検証
interface Logger {
log: (level: 'info' | 'error', message: string) => void;
}
describe('LoggerService', () => {
const mockLogger = mock<Logger>();
test('should log error', () => {
mockLogger.log('error', 'something went wrong');
expect(mockLogger.log).toHaveBeenCalledWith(
'error',
'something went wrong'
);
});
});
利点と注意点
利点
- 型安全性
- コンパイル時のエラー検知
- IDEの補完が効く
- リファクタリング時の安全性
- テストの品質向上
- インターフェースに忠実なモック
- 実装の詳細に依存しないテスト
- より読みやすいテストコード
注意点
- 実装への依存
- モックはインターフェースのみに依存するべき
- 実装の詳細までモックすると脆弱なテストになる
- 型定義の重要性
- 適切な型定義がないとメリットを活かせない
- インターフェースの設計が重要
発展的な使い方
ディープオブジェクトのモック
複雑なオブジェクト構造もモック化できます:
interface DeepObject {
level1: {
level2: {
method: (arg: string) => Promise<number>;
};
};
}
const mockDeep = mock<DeepObject>();
mockDeep.level1.level2.method.mockResolvedValue(42);
マッチャーの使用
より柔軟な引数のマッチングが可能です:
import { mock, any } from 'jest-mock-extended';
mockLogger.log.calledWith('error', any()).mockReturnValue();
おわりに
jest-mock-extendedを使用することで、型安全で保守性の高いテストコードを簡単に書くことができます。特にTypeScriptプロジェクトにおいて、テストのためのモック作成が大幅に簡単になります。実装の詳細に依存せず、インターフェースに基づいたテストを書くことで、より堅牢なテストスイートを構築できます。
Discussion