背景
ユニットテストを書くときに、
時刻周り(datetime
)のモックアウト が意外とやりにくい。
これは何故かというと datetime
の提供する関数がちょいちょい
C拡張モジュールとして書かれているため。
C拡張モジュールで書かれていると標準ライブラリの
unittest.mock で置き換えることができない。
解決方法
freezegun を使う。
$ pip install freezegun
名前のように、 datetime
で取得した時間を凍結することが出来る。
freezegunの使い方
(1) デコレータで修飾された関数の中でのみ時刻が置き換わる。
import freezegun
from datetime import datetime
@freezegun.freeze_time('2018-07-06 21:56:56')
def main():
print(datetime.now()) # 2018-07-06 21:56:56
(2) with構文で置き換える。
import freezegun
from datetime import datetime
dt = datetime(2018, 7, 6, 21, 56, 56)
def main():
with freezegun.freeze_time(dt):
print(datetime.now()) # 2018-07-06 21:56:56
(3) デコレータとしてもコンテキストマネージャとしても使わない場合
import freezegun
from datetime import datetime
def main():
freezer = freezegun.freeze_time('2018-07-06 21:56:56')
freezer.start() # ←こちらがキモ
try:
print(datetime.now())
finally:
freezer.stop() # ←こちらがキモ