2022.01.22  

【Python】単体テストのmockで例外を呼び出す(side_effect)

Python    

関数のモックに例外を設定する方法について記載します。
それには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の引数にしていしたhogehogeexcept ZeroDivisionError as e:eのとして出力されています。

コメント
現在コメントはありません。
コメントする
コメント入力

名前 (※ 必須)

メールアドレス (※ 必須 画面には表示されません)

送信