Freezegun 总是导致接收原始日期时间的 RuntimeWarning
Freezegun always causes RuntimeWarning of receiving naive datetime
我正在处理一个可以暂停组织的测试用例。
目前我正在使用 freezegun
来冻结固定时间,这是一个带有 tzinfo=pytz.UTC
.
的 datetime.datetime
对象
在下面的测试中,您将看到 self.fake_datetime
的打印,其中 returns 一个 tzaware
日期时间:2000-01-01 00:00:00+00:00
.
当测试运行时,我不断得到著名的RuntimeWarning
:
/usr/local/lib/python2.7/dist-packages/django/db/models/fields/init.py:1447: RuntimeWarning: DateTimeField Organization.suspended received a naive datetime (2000-01-01 00:00:00) while time zone support is active.
RuntimeWarning)
import datetime
import pytz
from freezegun import freeze_time
# crop
class OrganizationSuspendTestCase(TestCase):
def setUp(self):
self.organization = OrganizationFactory()
self.fake_datetime = datetime.datetime(2000, 1, 1, 0, 0, 0, tzinfo=pytz.UTC)
print self.fake_datetime
def test_suspend_organization(self):
"""
Case: An organization is being suspended with the suspend service.
Expected: The organization is updated with the suspending datetime and the reason.
"""
with freeze_time(self.fake_datetime):
mc_organization.services.organization.suspend(organization=self.organization, reason="Did not pay the bill")
self.assertEqual(self.organization.suspended, datetime.datetime(2000, 1, 1, 0, 0, 0))
我一直在尝试 freezegun timezone examples 但没有成功删除运行时警告。
关于如何正确解决这个问题有什么建议吗?我想在没有 RuntimeWarning
的情况下继续使用 Freezegun
。抑制是一种选择,但我不想这样做。
update -- 基于
的解决方案
服务在不知不觉中保存日期时间时区。旧情况已注释,新情况是实际代码。我考虑了很多 mocking
并假设保存在 service
中的日期时间将被 freezegun
测试用例中的时区感知日期时间对象模拟 - 但事实并非如此。
def suspend(organization, reason):
"""
Suspend an organization with the given reason.
:param mc_organization.models.Organization organization: The organization to suspend.
:param string reason: The reason of the suspending.
:return: None
"""
# organization.suspended = datetime.datetime.now() (Old sitation)
organization.suspended = timezone.now() # timezone aware situation.
organization.suspended_reason = reason
organization.save()
你好像是 trying to save an object with a timezone-naive datetime。要消除此警告,只需在您的应用程序中的所有位置使用可识别时区的日期时间。
您可以使用 django.utils.timezone
中的 Django timezone
模块,而不是使用 pytz
手动管理时区。它有一些快捷方法,您可以使用这些方法将原始日期时间转换为感知日期时间。
使用它的一个优点是,如果您在设置文件中更改时区设置,它会自动选择新时区,而使用 pytz
您必须在所有地方手动更新新时区.
from django.utils import timezone
fake_datetime = timezone.make_aware(timezone.datetime(2000, 1, 1, 0, 0, 0))
我正在处理一个可以暂停组织的测试用例。
目前我正在使用 freezegun
来冻结固定时间,这是一个带有 tzinfo=pytz.UTC
.
datetime.datetime
对象
在下面的测试中,您将看到 self.fake_datetime
的打印,其中 returns 一个 tzaware
日期时间:2000-01-01 00:00:00+00:00
.
当测试运行时,我不断得到著名的RuntimeWarning
:
/usr/local/lib/python2.7/dist-packages/django/db/models/fields/init.py:1447: RuntimeWarning: DateTimeField Organization.suspended received a naive datetime (2000-01-01 00:00:00) while time zone support is active. RuntimeWarning)
import datetime
import pytz
from freezegun import freeze_time
# crop
class OrganizationSuspendTestCase(TestCase):
def setUp(self):
self.organization = OrganizationFactory()
self.fake_datetime = datetime.datetime(2000, 1, 1, 0, 0, 0, tzinfo=pytz.UTC)
print self.fake_datetime
def test_suspend_organization(self):
"""
Case: An organization is being suspended with the suspend service.
Expected: The organization is updated with the suspending datetime and the reason.
"""
with freeze_time(self.fake_datetime):
mc_organization.services.organization.suspend(organization=self.organization, reason="Did not pay the bill")
self.assertEqual(self.organization.suspended, datetime.datetime(2000, 1, 1, 0, 0, 0))
我一直在尝试 freezegun timezone examples 但没有成功删除运行时警告。
关于如何正确解决这个问题有什么建议吗?我想在没有 RuntimeWarning
的情况下继续使用 Freezegun
。抑制是一种选择,但我不想这样做。
update -- 基于
服务在不知不觉中保存日期时间时区。旧情况已注释,新情况是实际代码。我考虑了很多 mocking
并假设保存在 service
中的日期时间将被 freezegun
测试用例中的时区感知日期时间对象模拟 - 但事实并非如此。
def suspend(organization, reason):
"""
Suspend an organization with the given reason.
:param mc_organization.models.Organization organization: The organization to suspend.
:param string reason: The reason of the suspending.
:return: None
"""
# organization.suspended = datetime.datetime.now() (Old sitation)
organization.suspended = timezone.now() # timezone aware situation.
organization.suspended_reason = reason
organization.save()
你好像是 trying to save an object with a timezone-naive datetime。要消除此警告,只需在您的应用程序中的所有位置使用可识别时区的日期时间。
您可以使用 django.utils.timezone
中的 Django timezone
模块,而不是使用 pytz
手动管理时区。它有一些快捷方法,您可以使用这些方法将原始日期时间转换为感知日期时间。
使用它的一个优点是,如果您在设置文件中更改时区设置,它会自动选择新时区,而使用 pytz
您必须在所有地方手动更新新时区.
from django.utils import timezone
fake_datetime = timezone.make_aware(timezone.datetime(2000, 1, 1, 0, 0, 0))