mockは今まで「便利らしいけどなるべく使わない方が良いんでしょう?壊れやすいとも聞くし・・・」という考えもあり、積極的に書こうとすることは無かった。
そもそも現職入社までユニットテストを書く機会が殆どなく、自分で書くコードもモックを用いた方が良いコードは無かった(或いは気がついていなかった)ので書くことは無かったが、理解できた方が良いなーということで調べた。
unittest.mock
オブジェクトのメソッドが1度だけ呼び出されていることを確認するテストを書いてみる。
Python 3.12.1
で検証した。
from unittest.mock import MagicMock class Book(): author = "" edition = "" def promotion(self): self.hoge() def hoge(self): pass real = Book() real.hoge = MagicMock() real.promotion() real.hoge.assert_called_once_with()
このように書くことで、`Book().promotion
がhoge
を1度だけ呼び出したことをテストできている。
逆に、下のように real.promotion()
を追加した後はreal.hoge.assert_called_once_with()
が失敗することがわかる。
# 上のコードの続き real.promotion() real.hoge.assert_called_once_with() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/unittest/mock.py", line 955, in assert_called_once_with raise AssertionError(msg) AssertionError: Expected 'mock' to be called once. Called 2 times. Calls: [call(), call()].
公式リファレンスではこの辺りに、他のメソッド含めて説明がある。
https://docs.python.org/ja/3/library/unittest.mock.html#unittest.mock.Mock.assert_called
- 少なくとも1回呼び出されたこと
- 1回だけ呼び出されたこと
- 1回呼び出され、かつ指定された引数で呼び出されたこと
などの種類があるようだった。
参考リンク
まだ全部見切れていないが、全部読むとしっかりと理解できそうなリンク。
余談
書籍 単体テストの考え方/使い方 にはこの辺りのことを第5章で言及しているので、改めて読み直していく。 スタブ・モックの違いなどもどこかで整理する。