Python 立即覆盖unittest的自动\u
我已经将数据库中事件的一些时间戳定义为Python 立即覆盖unittest的自动\u,python,django,unit-testing,Python,Django,Unit Testing,我已经将数据库中事件的一些时间戳定义为auto\u now\u add,因为信息应该在存储事件的同时与其时间戳一起存储 事件的描述类似于 class NewEvent(models.Model): ''' Individual event ''' name = models.CharField(max_length=100) quantity = models.FloatField(null=True) timestamp = models.Dat
auto\u now\u add
,因为信息应该在存储事件的同时与其时间戳一起存储
事件的描述类似于
class NewEvent(models.Model):
'''
Individual event
'''
name = models.CharField(max_length=100)
quantity = models.FloatField(null=True)
timestamp = models.DateTimeField(auto_now_add=True)
为了测试模块,我在test.py
文件的数据库中生成了一些信息,如下所示:
for event in EVENT_TYPES:
time = datetime.datetime.now() - datetime.timedelta(days=1)
for i in range(48):
time = time.replace(hour=i / 2)
NewEvent(name=event,
timestamp=time,
quantity=i).save()
我必须生成带有昨天时间戳的事件(然后模块将对它们进行汇总)。问题是您无法覆盖时间戳。时间戳,它是事件发生的时间戳,状态非常清楚
那么,如何为测试生成具有适当时间戳的数据呢?我有几个想法:
- 可能在模型类之外以不同的方式生成数据库数据。在哪里,如何
- 以某种方式定义一个不同的类,或者在测试过程中改变类的行为,比如
或者也许有更简单的方法。。。有什么想法吗?我已经设法用一个装置创建了覆盖默认值的数据 我创建了一个
test\u data.json
文件,其中的数据格式如下:
[
{
"model": "stats_agg.newevent",
"pk": 1,
"fields": {
"name": "event1",
"quantity":0.0,
"timestamp": "2010-02-15 00:27:40"
}
},
{
"model": "stats_agg.newevent",
"pk": 2,
"fields": {
"name": "event1",
"quantity":1.0,
"timestamp": "2010-02-15 00:27:40"
}
},
...
然后添加到测试单元中
class SimpleTest(TestCase):
fixtures = ['test_data.json']
对我来说,fixture的问题在于,我需要测试某些超过30天的记录是否不会被返回,而那些不超过30天的记录是否会被返回。。。使用静态装置无法做到这一点(以惰性方式)。因此,我选择模拟timezone.now函数,django使用该函数获取要使用的日期时间
from django.utils import timezone
class SomeTestCase(TestCase):
def test_auto_add(self):
now = timezone.now()
now_31 = now - datetime.timedelta(days=31)
self.mock('timezone.now', returns=now_31, tracker=None)
SomeObject.objects.create() # has auto_now_add field ...
对于模拟,我使用另一种处理方法是在创建实例后使用,这可能更有用,具体取决于您的用例 当在SQL级别执行
update
调用时,它将跳过验证、信号和自定义保存功能。它将需要一个二级数据库调用,这可能会影响性能,因此应该考虑使用它
for event in EVENT_TYPES:
time = datetime.datetime.now() - datetime.timedelta(days=1)
for i in range(48):
time = time.replace(hour=i / 2)
instance = NewEvent(name=event, quantity=i).save()
NewEvent.objects.filter(pk=instance.pk).update(timestamp=time)
作为一种简化,如何使用
timestamp=models.DateTimeField(auto\u now\u add=testing)
进行测试?这将很好,但在这种情况下,它应该类似于auto\u now\u add=not testing
,我认为…这是您的问题和示例,请随意修复它。有关动态选项,请参阅下面我的答案。固定装置不起作用,它们有严重问题。使用伪造日期时间是更好的选择:
for event in EVENT_TYPES:
time = datetime.datetime.now() - datetime.timedelta(days=1)
for i in range(48):
time = time.replace(hour=i / 2)
instance = NewEvent(name=event, quantity=i).save()
NewEvent.objects.filter(pk=instance.pk).update(timestamp=time)