【初学者向け】MockとMagicMockとは?

はじめに
Pythonでテストコードをみると、よく出てくるのが Mock(モック) と MagicMock(マジックモック) です。
初学者の方だと、名前は知っていても「結局なに?」「どっちを使えばいいの?」と迷う人は多いと思います。
この記事では、「Mockとは?」「MagicMockとは?」について説明し、その上でそれぞれの使い方について解説します。
Mockとは?
Mock(モック)とは、テストで使う“本物の代わりに動くダミー のことです。
- 本物を呼ぶと遅い/お金がかかる/環境に依存する
- テストでは「ロジック」だけを確認したい
そんなときに Mockを使えば、好きな戻り値を返すようにできる ので、外部依存を切り離してテストできます。
さらにMockは 「呼び出し回数」「引数」などの履歴を検証できる という機能も持っています。
MagicMockとは?
MagicMock(マジックモック)はMockを拡張したもの です。
Mockの機能はそのままに、さらに
- len(obj)
- for x in obj:
- obj[0]
といった 特殊メソッド(マジックメソッド) も自動でモック化できます。
つまり「リストっぽく」「ファイルっぽく」振る舞わせたいときに使うのがMagicMockです。
テストの種類とMockの役割
テストにはいくつか段階があります。
- 単体テスト … 関数やクラスなど、プログラムの部品単位で正しく動くか
- 結合テスト … 部品をつなげて正しく動くか
👉 Mock/MagicMockは 主に単体テストで使います。
単体テストでのMockの使い方
例:会員ランクに応じて割引メッセージを返す関数。
python
# app.py
def build_message(get_rank, user_id):
rank = get_rank(user_id) # ← DBや外部APIを想定
if rank == "gold":
return "10%OFF!"
return "通常価格です"
この get_rank がDBやAPI依存だと単体テストがややこしい。
そこでMockに置き換えます。
python
# test_app.py
import unittest
from unittest.mock import Mock
from app import build_message
class TestBuildMessage(unittest.TestCase):
def test_gold_member(self):
fake = Mock(return_value="gold") # 外部の代わり
msg = build_message(fake, user_id=123)
self.assertEqual(msg, "10%OFF!")
fake.assert_called_once_with(123) # 呼び出しも検証できる
👉 Mockを使うと 「ロジックだけ」 を確認でき、外部依存を切り離せるのです。
MagicMockが活きる例
例:カートに商品が入っているか確認する関数。
python
#def has_items(cart):
return len(cart) > 0
ここで普通のMockを渡すと len(cart) はエラーになります。
MagicMockならOK。
python
import unittest
from unittest.mock import MagicMock
from app import has_items
class TestCart(unittest.TestCase):
def test_cart_with_items(self):
cart = MagicMock()
cart.__len__.return_value = 2
self.assertTrue(has_items(cart))
def test_cart_empty(self):
cart = MagicMock()
cart.__len__.return_value = 0
self.assertFalse(has_items(cart))
👉 特殊メソッドを含むオブジェクト をモック化したいときはMagicMockを選びます。
疑問:全部MagicMockでよくないか
そう思うのですが、一応
- 動作はする → MagicMockはMockの機能をすべて持つ
- でも推奨されない
L MagicMockは多機能すぎて、存在しない属性でも動いてしまい間違いに気づきにくい
L Mockの方が「ただのダミー」だと意図が伝わりやすい
👉 ベストプラクティスは
- 基本はMock
- 特殊メソッドが必要なときだけMagicMock
が良いとのこと。
補足:スタブとの違い
- Stub(スタブ):決め打ちの値を返すだけの代用品
- Mock:Stubの機能に加えて「呼び出し履歴の検証」ができる
👉 MockはStubの進化版 と覚えておけばOKです。
スタブの記事はこちら↓
まとめ
- Mock = 本物の代わりに動く + 呼び出し検証ができる
- MagicMock = Mockの拡張版。len() など特殊メソッドを扱いたいときに使う
- スタブ = ただの代用品(Mockの基礎)
- 使い分け = 基本はMock、必要なときだけMagicMock
Discussion