2010-02-16 89 views
6

我定义了一些时间戳在数据库中auto_now_add事件,应将信息存储与它的时间戳,同时被存储的事件。覆盖auto_now的单元测试

事件的描述是一样的东西

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() 

我必须用昨天的时间戳生成事件(模块将会总结它们)。问题是你不能覆盖时间戳。时间戳是它生成的事件的时间戳,documentation表示非常清楚。

那么,如何生成与测试appropiate时间戳数据?我有几个想法:

  • 也许以不同的方式在Model类之外生成数据库数据。在哪里以及如何?
  • 不知怎的,定义不同的类或测试过程中改变类的行为方式不同,像

_

if testing: 
    timestamp = models.DateTimeField(auto_now_add=True) 
else: 
    timestamp = models.DateTimeField(auto_now_add=False) 

或者,也许有一个更简单的方法来做到这一点...任何想法?

+1

'timestamp = models.DateTimeField(auto_now_add = testing)'如何简化? –

+0

如果测试,'testing'变量将为真?这会很棒,但在这种情况下,它应该是'auto_now_add = not testing',我想... – Khelben

+0

这是你的问题和你的例子,随时修复它。 –

回答

2

我已经成功地创建数据覆盖使用固定的默认值。

我在下面的格式创建一个文件test_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'] 
+1

+1:赛程规则。 –

+2

赛程不统治,他们有严重的问题。使用[工厂](http://factoryboy.readthedocs.org/en/latest/orms.html) – SColvin

2

与灯具对我来说,问题是,我需要测试某些超过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 ... 

的嘲讽我用minimocktest

+0

伪造datetime是更好的选择:http://tech.yunojuno.com/mocking-dates-with-django – SColvin

1

处理这个另一种方式是在创建实例,这取决于你的使用情况,其可能更有用后使用QuerySet update

作为一个update调用SQL级就会跳过验证,信号和自定义保存功能被执行。它将需要可能影响性能的辅助数据库调用,因此应该考虑使用它。

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) 
相关问题