Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
ユニットテスト時に datetime.now() を置き換える
# -*- coding: utf-8 -*-
from datetime import datetime
@contextlib.contextmanager
def mock_datetime_now(module_path, return_value):
"""
適当なモジュールの datetime.now() を mock し、適当な日付を返すようにする。
>>> from datetime import datetime
>>> with mock_datetime_now('some_app.some_module.datetime', datetime(2015, 1, 1)):
... datetime.now()
datetime(2015, 1, 1, 0, 0, 0)
のように利用する。
"""
class DummyDatetime(datetime):
@classmethod
def now(cls):
return return_value
# dateime を持つモジュールを取得する
module_names = module_path.rstrip('.datetime').split('.')
module = __import__('.'.join(module_names))
for name in module_names:
module = getattr(module, name)
# 置き換えて yield
module.datetime = DummyDatetime
yield
# 置き換えたのを戻す
module.datetime = datetime
@podhmo

This comment has been minimized.

Copy link

@podhmo podhmo commented Apr 9, 2015

@tomoh1r

This comment has been minimized.

Copy link
Owner Author

@tomoh1r tomoh1r commented Apr 10, 2015

最終的にこうした。 : see このコメント

class DummyDatetime(object):
    """
    適当なモジュールの datetime.now() を mock し、適当な日付を返すようにする。

    >>> import mock
    >>> from datetime import datetime
    >>> with mock.patch('app.some_app.some_module.datetime',
    ...                 new=DummyDatetime(datetime(2015, 1, 1))):
    ...     datetime.now()
    datetime(2015, 1, 1, 0, 0, 0)

    のように利用する。
    """
    # XXX: メソッドがないと言われたら、随時テストに合うように追加願います。
    def __init__(self, dummy_current):
        self.now = lambda: dummy_current
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment