在上下文中模拟计时以创建具有 auto_now_add=True 字段 DateTimeField 的模型
Mock timing in a context to create models with a field DateTimeField with auto_now_add=True
我想模拟计时,以便能够在我的测试期间 设置 特定时间到 DateTimeField
和 auto_now_add=True
类型的字段,例如:
class MyModel:
...
created_at = models.DateTimeField(auto_now_add=True)
...
class TestMyModel(TestCase):
...
def test_something(self):
# mock current time so that `created_at` be something like 1800-02-09T020000
my_obj = MyModel.objects.create(<whatever>)
# and here my_obj.created_at == 1800-02-09T000000
我知道当前日期 always 用于此类字段,这就是为什么我正在寻找一种替代方法来以某种方式模拟系统计时,但 只是上下文.
我尝试了一些方法,例如,使用 freeze_time
创建上下文但没有用:
with freeze_now("1800-02-09"):
MyModel.objects.create(<whatever>)
# here the created_at doesn't fit 1800-02-09
Ofc 我猜,这是由于 auto_now_add=True
.
时幕后创建对象的机制所致
我不想删除 auto_now_add=True
and/or 使用默认值。
有没有一种方法可以模拟时间,以便我们可以让这种类型的字段在特定情况下获得我想要的时间?
我正在使用 Django 1.9.6
和 Python 3.4
好的,我找到了解决方案,它基于mock:
def mock_now():
return <mock time>
class TestMyModel(TestCase):
...
@mock.patch('django.utils.timezone.now', mock_now)
def test_as_decorator(self):
...
my_obj = MyModel.objects.create(<whatever>)
...
# here the created_at field has the mocked time :)
def test_as_context_manager(self):
mocked_dt = datetime.datetime(2015, 9, 3, 11, 15, 0)
with mock.patch('django.utils.timezone.now', mock.Mock(return_value=mocked_dt)):
my_obj = MyModel.objects.create(<whatever>)
# here the created_at field has the mocking time :)
扩展@trincchets 的回答,这里是上下文管理器,
from datetime import timedelta
from django.utils import timezone
from mock import patch, Mock
last_week = timezone.now() - timedelta(weeks=1)
with patch('django.utils.timezone.now', Mock(return_value=last_week)):
# Make your models/factories
# Carry on with normal time
你可以试试这个
from datetime import datetime
from django.test import TestCase
from mock import patch
class TestMyModel(TestCase):
@patch('django.utils.timezone.now', )
def test_something(self, mock_now):
mock_now.return_value = datetime(2015, 9, 3, 11, 15, 0)
我想模拟计时,以便能够在我的测试期间 设置 特定时间到 DateTimeField
和 auto_now_add=True
类型的字段,例如:
class MyModel:
...
created_at = models.DateTimeField(auto_now_add=True)
...
class TestMyModel(TestCase):
...
def test_something(self):
# mock current time so that `created_at` be something like 1800-02-09T020000
my_obj = MyModel.objects.create(<whatever>)
# and here my_obj.created_at == 1800-02-09T000000
我知道当前日期 always 用于此类字段,这就是为什么我正在寻找一种替代方法来以某种方式模拟系统计时,但 只是上下文.
我尝试了一些方法,例如,使用 freeze_time
创建上下文但没有用:
with freeze_now("1800-02-09"):
MyModel.objects.create(<whatever>)
# here the created_at doesn't fit 1800-02-09
Ofc 我猜,这是由于 auto_now_add=True
.
我不想删除 auto_now_add=True
and/or 使用默认值。
有没有一种方法可以模拟时间,以便我们可以让这种类型的字段在特定情况下获得我想要的时间?
我正在使用 Django 1.9.6
和 Python 3.4
好的,我找到了解决方案,它基于mock:
def mock_now():
return <mock time>
class TestMyModel(TestCase):
...
@mock.patch('django.utils.timezone.now', mock_now)
def test_as_decorator(self):
...
my_obj = MyModel.objects.create(<whatever>)
...
# here the created_at field has the mocked time :)
def test_as_context_manager(self):
mocked_dt = datetime.datetime(2015, 9, 3, 11, 15, 0)
with mock.patch('django.utils.timezone.now', mock.Mock(return_value=mocked_dt)):
my_obj = MyModel.objects.create(<whatever>)
# here the created_at field has the mocking time :)
扩展@trincchets 的回答,这里是上下文管理器,
from datetime import timedelta
from django.utils import timezone
from mock import patch, Mock
last_week = timezone.now() - timedelta(weeks=1)
with patch('django.utils.timezone.now', Mock(return_value=last_week)):
# Make your models/factories
# Carry on with normal time
你可以试试这个
from datetime import datetime
from django.test import TestCase
from mock import patch
class TestMyModel(TestCase):
@patch('django.utils.timezone.now', )
def test_something(self, mock_now):
mock_now.return_value = datetime(2015, 9, 3, 11, 15, 0)