2010-02-16 86 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) 
相關問題