雑念ストレージ

プログラミング関連のメモとか

【Python】MagicMockの使い方メモ1 - MagicMockとは

普段なんとなく使っていたMagicMockについて調べ直したのでまとめる。

MagicMockとは

いきなりうまく説明できないけど、定義していないメソッドでも呼べてしまう、ぐにゃぐにゃの粘土みたいなイメージ、、

m = MagicMock()

func1_result = m.func1()
print(func1_result)
# <MagicMock name='mock.func1()' id='4313588304'>

func2_result = func1_result.func2()
print(func2_result)
# <MagicMock name='mock.func1().func2()' id='4313657552'>

上の例では、生成したインスタンスに対して、定義していないメソッドfunc1を呼び出している。
結果、func1は新しいMagicMockインスタンスを返している。

さらにそのインスタンスに対してメソッドfunc2を呼び出しても、同様に新しいMagicMockインスタンスを返している。

return_valueでメソッドが返す値を指定する

そのままでは単にMagicMockのインスタンスを返すだけで役に立たない。
MagicMockは、メソッドが返す値をreturn_valueに設定できる。

m = MagicMock()
m.func1.return_value = "hoge"

print(m.func1())
# hoge

side_effectでメソッドが呼ばれるたびに返す値を変える

メソッドを複数回呼び出したときに、返す値を変えたい場合はside_effectを使う。

m = MagicMock()
m.func1.side_effect = ["hoge1", "hoge2"]

print(m.func1())
# hoge1
print(m.func1())
# hoge2

メソッドを呼ばれたときに例外を投げたい場合もside_effectに設定する。

m = MagicMock()
m.func1.side_effect = Exception("テスト用の例外")

try:
    m.func1()
except Exception as e:
    print(e)
    # テスト用の例外

値を返したり、例外を投げたりを組み合わせることもできる。
以下のコードは、3回目のfunc1で例外を投げている。

m = MagicMock()
m.func1.side_effect = ["hoge1", "hoge2", Exception("テスト用の例外")]

m.func1()
m.func1()

try:
    m.func1()
except Exception as e:
    print(e)

ユニットテストでの使い方は、後で書く、、