pythonでdatetime.dateをpatchする
datetime.date.todayやdatetime.nowを使ったコードでテストのために日付を固定したいということがよくあるので、
datetime.dateをpatchする方法を試してみる
from unittest import TestCase from dateutil.relativedelta import relativedelta from mock import patch import datetime class DateTodayMockTest(TestCase): def setUp(self): class FakeDate(datetime.date): @classmethod def today(cls): return cls(2014, 1, 1) patcher = patch('datetime.date', FakeDate) self.addCleanup(patcher.stop) patcher.start() def test_today(self): today = datetime.date.today() self.assertEquals(today.year, 2014) self.assertEquals(today.month, 1) self.assertEquals(today.day, 1) tomorrow = today + relativedelta(days=1) self.assertEquals(tomorrow.year, 2014) self.assertEquals(tomorrow.month, 1) self.assertEquals(tomorrow.day, 2) day_after_day = tomorrow + relativedelta(days=1) self.assertEquals(day_after_day.year, 2014) self.assertEquals(day_after_day.month, 1) self.assertEquals(day_after_day.day, 12)
上記のようにpatchしたdatetimeを使ったテストでrelativedeltaを2回使うとエラーになった。
2度めのrelativedeltaで以下のエラーになる(day_after_day = tomorrow + relativedelta(days=1))
Traceback (most recent call last): File "date_today_mock_test.py", line 29, in test_today day_after_day = tomorrow + relativedelta(days=1) File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/dateutil/relativedelta.py", line 247, in __radd__ raise TypeError, "unsupported type for add operation" TypeError: unsupported type for add operation
調べてみるとrelativedelta.__radd__の以下の箇所でエラーになっている
def __radd__(self, other): if not isinstance(other, datetime.date): raise TypeError, "unsupported type for add operation"
tomorrowはdatetime.dateのオブジェクトなのになぜ?と最初思ったけど、よく考えたらdatetime.dateはpatchしてるので、otherがFakeDateのオブジェクトじゃないとエラーになるってことなんだろう。
一度目のrelativedeltaではtodayがFakeDateのオブジェクトなので上記の部分は通ったが、__radd__が通常のdateオブジェクトを返すので2度めではエラーになる。
isinstanceの挙動をオーバーライドできれば解決できそうだけど、続きはまた今度