Jestテスト|モック(Mock)を活用したテストコードの書き方
Jestテストにおけるモック(Mock)とは?
5/28/2025
モック(Mock)とは?
実際の関数やAPIなどの「本物の処理の代わりに使うダミー(偽物)」のこと。
Mockを使用すると、下記のようなことができるようになる。
- 外部APIなどテスト時に呼びたくない処理を回避する
- 未実装の関数でも先にテストできる
- 関数の呼び出し状況を検証できる
モックの「作り方」にはいくつかある
🛠 よく使うモックの作り方:
モックの作り方 | 説明 |
|---|---|
| 自分でゼロからモック関数を作る |
| すでにある関数の動きを監視・モック化する |
| ファイル・モジュール全体をモックに置き換える |
jest.fn()
未実装の関数を仮で作ってテストしたいときや、外部の関数の代わりにテスト用の関数を使いたいときに便利。
🔸①テスト対象のモジュール|apiHandler.ts
例として、データ取得後に処理(callback)を呼ぶ関数fetchDataを作成。
export function fetchData(callback: (data: string) => void) {
// ここは本来、APIからデータ取得処理などがある想定
// 今は簡単に即時でコールバック呼び出し
callback('取得したデータ');
}callbackは引数で、関数を受け取る形。つまりfetchDataに「こういう処理をしてね」という関数を渡すことができる。fetchDataの中で、そのcallback関数を呼び出すとき、'取得したデータ'という文字列を引数として渡す。
🔸②これを使う関数|dataProcessor.ts
import { fetchData } from './apiHandler';
export function processData() {
fetchData((result) => {
console.log('データ処理中:', result);
});
}- ここで
fetchDataに渡しているのは、匿名関数(無名関数)。(result) => {console.log('データ処理中:', result); }がその関数。 - この無名関数は 「fetchDataが呼び出すコールバック関数」 になる。
resultは、このコールバック関数の引数。fetchData関数内で、コールバック関数として呼び出されたこの匿名関数は、引数として'取得したデータ'を渡されている。そのためresult = '取得したデータ'となる。
🔸③テストコード|fetchData.test.ts
fetchDataが ちゃんとコールバックを呼んでいるか- コールバックが 正しい引数で呼ばれているか
import { fetchData } from './apiHandler';
test('fetchDataはコールバックを正しい引数で呼ぶ', () => {
const mockCallback = jest.fn(); // 空のモック関数を作成
fetchData(mockCallback); // モック関数をコールバックに渡して実行
// 関数が1回以上呼ばれたかチェック
expect(mockCallback).toHaveBeenCalled();
// 呼ばれた時の引数が '取得したデータ' かチェック
expect(mockCallback).toHaveBeenCalledWith('取得したデータ');
});jest.spyOn()
- 既存のモジュールの 特定の関数(メソッド)を監視(spy) できる
- 元の関数の実装を一時的に「監視」し、呼び出し状況を記録できる
- 必要に応じて、元の実装を「モック(差し替え)」することもできる
🔸①テスト対象のモジュール|logger.ts
export const logger = {
log: (message: string) => {
console.log('Log:', message);
}
};🔸②これを使う関数|app.ts
import { logger } from './logger';
export function greetUser(name: string) {
logger.log(`Hello, ${name}!`);
}🔸③テストコード|logger.test.ts
greetUserを呼んだ時にlogger.logが 正しく呼ばれたか- 呼ばれた時の引数は 期待どおりか
import * as loggerModule from './logger';
import { greetUser } from './app';
test('greetUserはlogger.logを正しい引数で呼ぶ', () => {
// logger.log を監視(spy)しつつ、実装は差し替えない(本来のconsole.logは呼ばれる)
const spy = jest.spyOn(loggerModule.logger, 'log');
greetUser('Yamada');
// spyが呼ばれたかチェック
expect(spy).toHaveBeenCalled();
// spyが呼ばれたときの引数をチェック
expect(spy).toHaveBeenCalledWith('Hello, Yamada!');
spy.mockRestore(); // 監視解除(後続のテストに影響しないように)
});jest.mock()
- モジュール全体を丸ごとモック(偽物)に差し替えるための関数
- 本物の実装を使わずに、テスト用のダミー実装を指定できる
- 外部APIやファイル読み込みなど、テスト環境で動かしたくない処理を差し替えるのに便利
🔸①テスト対象のモジュール|api.ts
export const fetchData = async () => {
const response = await fetch('https://example.com/data');
const data = await response.json();
return data.message;
};🔸②これを使う関数|app.ts
import { fetchData } from './api';
export async function showMessage() {
const message = await fetchData();
return `メッセージ: ${message}`;
}🔸③テストコード|api.test.ts
- テスト時に実際の外部通信(fetch)を行いたくない
fetchDataの戻り値を自由にコントロールしたい
// app.test.ts
jest.mock('./api', () => ({
fetchData: jest.fn().mockResolvedValue('モックのメッセージ')
}));
import { fetchData } from './api';
import { showMessage } from './app';
test('showMessageはモックデータを返す', async () => {
const result = await showMessage();
expect(fetchData).toHaveBeenCalled(); // fetchDataが呼ばれたかチェック
expect(result).toBe('メッセージ: モックのメッセージ');
});