普段なんとなく使っていた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'>
上の例では、生成したインスタンスm
に対して、定義していないメソッド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)
ユニットテストでの使い方は、後で書く、、