# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import base64
from datetime import timedelta, datetime
from freezegun import freeze_time
from django.conf import settings
from django.core.urlresolvers import reverse
from django.core.management import call_command
from django.test import Client
from django.core.files.uploadedfile import SimpleUploadedFile
class timetravel(object):
"""
Fast forward in time with simulated CRON jobs (used for unit testing)
"""
delta = None
def __init__(self, *args):
self.initial_now = datetime.now()
if isinstance(args[0], timedelta):
self.delta = args[0]
self.now = datetime.now() + self.delta
elif isinstance(args[0], datetime):
self.now = args[0]
if args[0] > self.initial_now:
self.delta = args[0] - self.initial_now
else:
self.delta = self.initial_now - args[0]
else:
print("Please provide a datetime or timedelta object as argument")
# import IPython
# IPython.embed()
#self.now = self.initial_now
#self.freezer = freeze_time(self.now)
#self.freezer.start()
def __enter__(self):
# Traveling in the past, we don't run cron jobs backward
if self.now < self.initial_now:
self.now = self.now - self.delta
self.freezer = freeze_time(self.now)
# import IPython
# IPython.embed()
self.freezer.start()
# Traveling in the future, run cron jobs
else:
self.now = self.initial_now
self.freezer = freeze_time(self.now)
self.freezer.start()
hours = self.delta.total_seconds() / 60 / 60
weekday = self.now.weekday()
month = self.now.month
year = self.now.year
for i in range(1, int(hours)+1):
call_command('cron', hourly=True, verbosity=0)
if weekday != self.now.weekday():
weekday = self.now.weekday()
call_command('cron', daily=True)
if self.now.weekday() == 6 and weekday != self.now.weekday():
call_command('cron', weekly=True)
if self.now.month != month:
month = self.now.month
call_command('cron', monthly=True)
if self.now.year != year:
year = self.now.year
call_command('cron', yearly=True)
self.freezer.stop()
self.now = self.now + timedelta(hours=1)
self.freezer = freeze_time(self.now)
self.freezer.start()
return self.now
# import IPython
# IPython.embed()
def __exit__(self, *args):
self.freezer.stop()
timetravel
存在问题。通常情况下,它应该固定论证中的时间,但这不是这种情况。
def test_product_reg_p01_1month(self):
with timetravel(datetime(2017, 03, 14)) as now:
self._test_product_configurations(**{
'loan_config': {
'product-id' : 1,
'frequency' : '1month',
'first_debit_date' : now + timedelta(days=17),
'second_debit_date' : now
},
'product_config':{
...
},
}
)
通常,类timetravel
应该在代码中修复当前日期。在test_product_reg_p01_1month
中,我们使用带有context manager
的{{1}}调用timetravel
。如果我们查询数据库,我们获取
datetime(2017, 03, 14)
但是,In [2]: customer_product.deposit_date
Out[2]: FakeDate(2017, 3, 14)
In [3]: datetime.now()
Out[3]: FakeDatetime(2017, 3, 13, 23, 55, 54, 708200)
应该等于明天的日期。
谢谢!