関数のモックに例外を設定する方法について記載します。
それにはside_effect
という属性を使用します。
下記の例ではpatch
を利用しています。そちらの書き方について知りたい方は次の記事をご参照ください。【Python】unittest.mock.patchの使い方
結論
例えば、ZeroDivisionError
を返すモックを作成する場合は次のように記述します。
@patch("モックにしたい関数へのパス")
def test_case_error_01(self, mock_01):
mock_01.side_effect = ZeroDivisionError()
また、単なるException
の場合は次のように記述します。
@patch("モックにしたい関数へのパス")
def test_case_error_01(self, mock_01):
mock_01.side_effect = Exception()
except ZeroDivisionError as e:
のようにe
の値も設定したい場合は、以下のようにZeroDivisionError
の引数に値を指定します。この例ではhoge
としています。
@patch("モックにしたい関数へのパス")
def test_case_error_01(self, mock_01):
mock_01.side_effect = ZeroDivisionError("hoge")
具体例
次のようなソースmain_process.py
があり、unfinished()
をモックにしてそれぞれの例外をテストしたいとする。
def unfinished():
return print("未完成の関数")
def execute():
try:
# モックにしてテストする
unfinished()
# 以下の例外をテストしたい
except KeyError as e:
print(f"エラー:{e}")
return "error_1"
except ZeroDivisionError as e:
print(f"エラー:{e}")
return "error_2"
except Exception as e:
print(f"エラー:{e}")
return "error_3"
if __name__ == "__main__":
execute()
例えばunfinished
関数からZeroDivisionError
の例外が呼び出された場合のテストコードは次のようになります。
テスト対象のソース main_process.py
へのパスはwork.src.main_process
とします。
import unittest
from unittest.mock import patch
from work.src import main_process
class test_main_process(unittest.TestCase):
@patch("work.src.main_process.unfinished")
def test_case_error_01(self, execute_mock):
# モックの設定
execute_mock.side_effect = ZeroDivisionError("hogehoge")
# テストの実行
result = main_process.execute()
self.assertEqual(result, "error_2")
if __name__ == "__main__":
unittest.main()
以下は実行結果です。
ZeroDivisionError
をキャッチするとexecute
関数からerror_2
が返ってくる想定であり、予想通りの結果であったためOKが出力されています。
Testing started at 11:28 ...
エラー:hogehoge
Ran 1 test in 0.008s
OK
エラー:hogehoge
の部分はモックのZeroDivisionError
の引数にしていしたhogehoge
がexcept ZeroDivisionError as e:
のe
のとして出力されています。