Python

[python][unittest] datetimeのユニットテスト

背景

ユニットテストを書くときに、
時刻周り(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() # ←こちらがキモ

freezegunのレポジトリ

https://github.com/spulec/freezegun

参考

コメントを残す