Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在Django 1.5.5测试中模拟datetime.date.today()方法_Python_Django_Testing_Mocking - Fatal编程技术网

Python 如何在Django 1.5.5测试中模拟datetime.date.today()方法

Python 如何在Django 1.5.5测试中模拟datetime.date.today()方法,python,django,testing,mocking,Python,Django,Testing,Mocking,我有一组测试依赖于使用python模拟库模拟日期,以及@mock.patchdecorator,以及找到的日期模拟代码示例。使用这个,我们有一个FakeDate类: class伪造日期(原始日期): “datetime.date的伪替换项,可用于模拟测试。” 定义(cls,*ARG,**kwargs): 返回原始日期。新日期(原始日期,*args,**kwargs) 在我们的测试中,我们有: from datetime导入日期为实际日期 @mock.patch('datetime.date',

我有一组测试依赖于使用python模拟库模拟日期,以及
@mock.patch
decorator,以及找到的日期模拟代码示例。使用这个,我们有一个FakeDate类:

class伪造日期(原始日期):
“datetime.date的伪替换项,可用于模拟测试。”
定义(cls,*ARG,**kwargs):
返回原始日期。新日期(原始日期,*args,**kwargs)
在我们的测试中,我们有:

from datetime导入日期为实际日期
@mock.patch('datetime.date',FakeDate)
def测试(星期一)自日期起(自我):
FakeDate.today=classmethod(lambda cls:real_date(2014,1,1))#一个星期三
self.assertNotEqual(datetime.date.today(),real_date.today())
self.assertEqual(datetime.date.today().year,2014)
#等等。。
在我将Django从1.4.8升级到1.5.5之前,一切都在运行。不幸的是,现在模拟日期导致测试失败,但仅限于模型保存操作。堆栈跟踪如下所示:

文件“/site packages/django/db/models/base.py”,第546行,保存
强制更新=强制更新,更新字段=更新字段)
文件“/site packages/django/db/models/base.py”,第650行,在save_base中
结果=管理器。\插入([self],字段=字段,返回\u id=update\u pk,using=using,raw=raw)
文件“/site packages/django/db/models/manager.py”,第215行,插入
返回insert_查询(self.model、objs、字段、**kwargs)
文件“/site packages/django/db/models/query.py”,第1675行,插入查询
return query.get\u编译器(using=using).execute\u sql(return\u id)
文件“/site packages/django/db/models/sql/compiler.py”,第942行,在execute\u sql中
对于sql,self.as_sql()中的参数为:
as_sql中的文件“/site packages/django/db/models/sql/compiler.py”,第900行
对于self.query.objs中的obj
文件“/site packages/django/db/models/fields/_init__.py”,第304行,在get_db_prep_save中
准备就绪(错误)
文件“/site packages/django/db/models/fields/_init__.py”,第738行,在get_db_prep_值中
value=self.get\u prep\u值(value)
文件“/site packages/django/db/models/fields/_init__.py”,第733行,在get_prep_值中
返回self.to_python(值)
文件“/site packages/django/db/models/fields/_init__uuuu.py”,第697行,在to_python中
已解析=解析日期(值)
parse_date中第36行的文件“/site packages/django/utils/dateparse.py”
匹配=日期匹配(值)
TypeError:应为字符串或缓冲区
我已经通过pdb进入Django源代码,问题似乎就在这里(在:

def to_python(self,value):
如果值为“无”:
返回值
如果isinstance(值,datetime.datetime):
如果设置.USE_TZ和时区.is_aware(值):
#将感知日期时间转换为默认时区
#在将它们定为日期之前(#17742)。
默认时区=时区。获取默认时区()
value=timezone.make_naive(值,默认_时区)
返回值.date()

if isinstance(value,datetime.date):#我对这一问题的调查是作为一组编辑进行的,但其长短不一的是,在1.4和1.5之间对to_python方法的更改意味着任何既不是有效的datetime.date也不是有效的datetime.datetime的内容都必须是字符串才能通过

它看起来(没有太多进一步的挖掘)好像
django.utils.encoding.smart\u str
方法在1.5中被删除了,尽管它被
smart\u text
取代,但它从未进入到
to\u python
方法中

我在django Trac实例中提出了一个问题

我也为这个问题创建了一个补丁,但显然这可能永远都不会成功(而且这个补丁是针对1.5.x的,它已经过时了,所以我真的不指望它成功)

[编辑1:解决方案!]


有一个解决方案;-)-我在这里写了一篇文章-,关键是重写FakeDateinstancecheck方法,这样在比较real datetime.date和FakeDate时,就得到了True。我将一些示例FakeDate类和相关测试的要点放在一起,以供参考-

FWIW,这看起来像是导致使用RQ时不使用模拟日期/日期时间的同一种平等性测试失败,因为RQ也被它们阻塞(无法pickle)了,您真正的模拟是否比今天返回一个固定值要复杂得多,以至于您需要模拟整个课堂?将补丁('datetime.date.today')简单的
和今天一样:today.return\u value=datetime.date(2014,1,1)
应该避免所有类型的复杂性…你们不能把今天模拟成datetime.date是一个内置类型-这就是整个线程的要点(试着谷歌搜索“不能设置内置/扩展类型'datetime.date'的属性”-或阅读问题中引用的文章,该文章对问题有很好的总结)。
> /site-packages/django/db/models/fields/__init__.py(685)to_python()
    684         import ipdb; ipdb.set_trace()
--> 685         if value is None:
    686             return value
ipdb> value
datetime.date(2012, 12, 7)
ipdb> isinstance(value, datetime.date)
False
ipdb> type(value)
<type 'datetime.date'>
ipdb> type(datetime.date)
<type 'type'>
ipdb> datetime.date
<class 'testutils.FakeDate'>
ipdb> datetime.datetime
<type 'datetime.datetime'>
# value = FakeDate(2012, 12, 31)
# code fails the isinstance(datetime.date) test
value = smart_str(value)
# value is now a string '2012-12-31'
parsed = parse_date(value)
# inside parse_date we try a regex match
match = date_re.match(value)
# because we have called smart_str, this now parses as a date