😎
[Python] unittest.mock チートシート
Python の unittest.mock
に関するチートシート。
※ここでは MagicMockは使わずに patch
を使っています。あくまで自分用のチートシートなので、テストコードはかなり簡潔に書いています。
公式のドキュメントはこちら
→ https://docs.python.org/ja/3/library/unittest.mock.html
from unittest.mock import patch
from path.to.foo import Foo
class TestFoo:
# patch は何度でも指定できる
# patch ではなく patch.object を使うことで、参照元にコードジャンプしやすくなる
@patch.object(Foo, 'do_something')
@patch.object(Foo, 'check_if_ok')
def test(
# 引数の順序は、デコレータで指定した順序の逆になる(Pythonの言語仕様)
mock_check_if_ok,
mock_do_something,
):
# 例外を投げさせる
mock_check_if_ok.side_effect = Exception('NG!')
# 返り値を設定する
mock_do_something.return_value = True
# 1度も実行されていない
assert mock_do_something.assert_not_called()
mock_do_something(1,2,3)
# 実行された
assert mock_do_something.called
# 少なくとも1度実行された
assert mock_do_something.assert_called()
# 1度だけ実行された
assert mock_do_something.assert_called_once()
# 1度だけ実行された(引数指定)
assert mock_do_something.assert_called_once_with(1,2,3)
# 最後に実行された際の引数
args = mock_do_something.call_args.args
assert args[0] == 1
mock_do_something(key='abc', value=100)
# N回実行された
assert mock_do_something.call_count = 2
# 最後に実行された際のキーワード引数
kargs = mock_do_something.call_args.kargs
assert kargs['key'] == 'abc'
# 今までに以下のように実行されたことがある
assert mock_do_something.assert_any_call(1,2,3)
# これまでの実行された引数
assert mock_do_something.call_args_list == ...
以下、個人的な所感。
- 自前で MagicMock() するとモックを元に戻す手間が発生するので、 patch デコレータを使うのが良さそう
- assert_called() よりは called の方がシンプルで良い
- call_args には最後に実行された引数が入っている、と覚えておく
- assert_any_call() は便利だけど、名称に any が入っているのでちょっと拒否感がある
- assert_has_calls() は使うことはあまり無さそう… 実装を変えたらすぐにテストが壊れそう any_order=True を指定しても良いけど
- call オブジェクトとか気にしたくないので、それを意識させないテストコードにするのが良さそう
Discussion