Skip to content

Instantly share code, notes, and snippets.

@tomoh1r
Created April 9, 2015 07:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save tomoh1r/8ae8d49633960cbf6bc5 to your computer and use it in GitHub Desktop.
Save tomoh1r/8ae8d49633960cbf6bc5 to your computer and use it in GitHub Desktop.
ユニットテスト時に 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
Copy link

podhmo commented Apr 9, 2015

@tomoh1r
Copy link
Author

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