モックオブジェクトとは?

テストにおけるモックオブジェクト(Mock Object)とは、実際のオブジェクトや外部サービスの代わりに使う、テスト用の疑似的なオブジェクトです。
API、データベース、外部ライブラリなどに依存する処理をテストするとき、実際に外部へアクセスせずに、期待する動作を再現できます。
また、モックを使うと、メソッドが呼び出された回数や、渡された引数なども確認できます。
モックオブジェクトの役割
モックオブジェクトは、次のような場面で役立ちます。
- 外部サービスへの依存を避ける: APIやデータベースへ実際にアクセスせずにテストできます。
- テストを高速化する: 通信やファイル操作を省略できるため、テストの実行が速くなります。
- 呼び出しを検証できる: 関数が正しい回数・正しい引数で呼ばれたか確認できます。
- 失敗時の動作を再現できる: APIエラーや通信失敗などを意図的に再現できます。
モックオブジェクトの使い方
モックオブジェクトを使ったテストは、基本的に次の流れで行います。
- モックオブジェクトを作成する: 外部APIやデータベースなど、テスト対象が依存しているものを疑似的に作成します。
- メソッドの動作を定義する: モックのメソッドが呼び出されたときに返す値や動作を設定します。
- テスト対象の処理を実行する: 実際の依存先の代わりにモックを渡してテストします。
- 結果を検証する: 戻り値や、モック関数が呼び出されたかどうかを確認します。
具体例: モックオブジェクトを使ったJavaScriptテスト
ここでは、fetchData()関数が外部APIからデータを取得する場面を想定します。
テスト対象の関数
async function fetchData(api) {
const response = await api.getData();
return response;
}
module.exports = fetchData;
この関数は、引数として受け取ったapiオブジェクトのgetData()メソッドを呼び出します。
ステップ1: モックオブジェクトを作成する
const fetchData = require("./fetchData");
const mockApi = {
getData: jest.fn(() => Promise.resolve({ data: "sample data" }))
};
ここでは、mockApiというモックオブジェクトを作成しています。
jest.fn()を使うことで、呼び出し回数や引数を検証できるモック関数を作成できます。
ステップ2: モックオブジェクトをテストに組み込む
test("fetchData calls API and returns data", async () => {
const result = await fetchData(mockApi);
expect(result.data).toBe("sample data");
expect(mockApi.getData).toHaveBeenCalled();
});
このテストでは、fetchData()がモックAPIを呼び出し、期待したデータを返すか確認しています。
fetchData(mockApi)を実行します。- 戻り値の
dataが"sample data"であることを確認します。 mockApi.getData()が呼び出されたことを確認します。
ステップ3: 引数の検証
モック関数では、どのような引数で呼び出されたかも確認できます。
const mockLogger = {
log: jest.fn()
};
mockLogger.log("保存しました");
expect(mockLogger.log).toHaveBeenCalledWith("保存しました");
toHaveBeenCalledWith()を使うと、関数が指定した引数で呼び出されたかを確認できます。
モックオブジェクトのメリット
モックオブジェクトを使用すると、次のようなメリットがあります。
- 外部環境に依存しない: APIやデータベースが使えない状態でもテストできます。
- テストが安定する: 通信状況や外部サービスの状態に左右されません。
- テストが速くなる: 実際の通信や重い処理を省略できます。
- 異常系を再現しやすい: エラーや失敗時の処理を意図的に確認できます。
モックとスタブの違い
テストでは、モックとスタブという言葉がよく使われます。どちらも実物の代わりに使うものですが、目的が少し異なります。
| 種類 | 主な目的 | 特徴 |
|---|---|---|
| モック | 呼び出しを検証する | メソッドが呼ばれた回数や引数を確認する。 |
| スタブ | 決まった値を返す | テストに必要なデータやレスポンスを用意する。 |
簡単に言えば、スタブは「代わりの値を返すもの」、モックは「呼び出されたかどうかも確認するもの」と考えると分かりやすいです。
モックを使うときの注意点
モックは便利ですが、使いすぎるとテストが実際の動作から離れてしまうことがあります。
- 何でもモック化しすぎると、実際の連携ミスに気づきにくくなります。
- モックの動作が本物のAPIやオブジェクトと違うと、テストの意味が薄くなります。
- 重要な処理では、モックを使った単体テストだけでなく、実際の連携を確認する統合テストも必要です。
モックは、主に単体テストで特定の処理だけを確認したい場合に使うと効果的です。
初心者が覚えておきたいポイント
- モックオブジェクトは、実物の代わりに使うテスト用のオブジェクトです。
- APIやデータベースに実際にアクセスせずにテストできます。
- Jestでは
jest.fn()を使って簡単にモック関数を作成できます。 - モックでは、呼び出し回数や引数を検証できます。
- モックを使いすぎると実際の動作との差が出るため、使いどころを意識しましょう。
まとめ
- モックオブジェクトは、実際の依存先を模倣するテスト用オブジェクトである。
- 外部APIやデータベースに依存せずにテストできる。
- Jestでは
jest.fn()を使ってモック関数を作成できる。 - モックを使うと、関数の呼び出し回数や引数を検証できる。
- スタブは主に値を返すために使い、モックは呼び出しの検証にも使う。
- 単体テストでは便利だが、必要に応じて統合テストも行うことが重要である。