2010-02-16 17 views
6

के लिए auto_now ओवरराइट करें मैंने डेटाबेस में auto_now_add के रूप में डेटाबेस के लिए कुछ टाइमस्टैम्प परिभाषित किए हैं, क्योंकि जानकारी को संग्रहीत किया जाता है, उसी समय जानकारी के समय के साथ संग्रहीत किया जाना चाहिए।unittest

घटनाओं का विवरण, इस तरह से

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 बताता है कि यह स्पष्ट रूप से है।

तो, परीक्षण के लिए एप्रोपिएट टाइमस्टैम्प के साथ डेटा कैसे उत्पन्न करें? मेरे पास कई विचार हैं:

  • शायद मॉडल कक्षाओं के बाहर डेटाबेस डेटा को अलग-अलग तरीके से उत्पन्न करें। कहां और कैसे?
  • किसी तरह एक अलग वर्ग को परिभाषित या परीक्षण के दौरान वर्ग व्यवहार करने के लिए बदलने के अलग ढंग से,

की तरह कुछ _

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

या हो सकता है कि इस ... कोई भी विचार करने के लिए एक और भी आसान रास्ता नहीं है?

+1

सरलीकरण के रूप में 'timestamp = models.DateTimeField (auto_now_add = परीक्षण) 'के बारे में कैसे? परीक्षण के बाद –

+0

'परीक्षण' चर सही होगा? यह बहुत अच्छा होगा, लेकिन इस मामले में, यह 'auto_now_add = परीक्षण नहीं' जैसा होना चाहिए, मुझे लगता है ... – 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 दिन पुराने नहीं हैं ... स्थिर फिक्स्चर का उपयोग करके यह नहीं किया जा सकता है (आलसी तरीके से)। तो मैंने जो करना चुना है वह टाइमज़ोन है .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

फ़ोकिंग डेटाटाइम बहुत बेहतर विकल्प है: http://tech.yunojuno.com/mocking-dates-with-django – SColvin

1

का उपयोग इस से निपटने का एक और तरीका है उदाहरण बनाई गई है जो आपके उपयोग के मामले के आधार पर अधिक उपयोगी हो सकता बाद एक QuerySet update उपयोग करने के लिए है।

एसक्यूएल स्तर पर 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) 
संबंधित मुद्दे