Overwrite auto_now for unittest

后端 未结 3 346
北荒
北荒 2021-01-12 15:50

I\'ve defined some timestamps for events in the database as auto_now_add, as the information should be stored with it\'s timestamp the same time the event is st

相关标签:
3条回答
  • 2021-01-12 16:27

    I've managed to create data overriding the default values using a fixture.

    I've created a test_data.json file with the data in the following format:

    [
    {
        "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"
         }
    },
    ...
    

    and then add to the test unit

    class SimpleTest(TestCase):
       fixtures = ['test_data.json']
    
    0 讨论(0)
  • 2021-01-12 16:42

    Another way of handling this is to use a QuerySet update after the instance is created which may be more useful depending upon your use case.

    As an update call is performed at the SQL level it will skip validation, signals and and custom save functionality. It will require a secondary database call which can impact performance so it should be used with consideration.

    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)
    
    0 讨论(0)
  • 2021-01-12 16:50

    The problem with fixtures for me, is that I need to test that certain records that are older than 30 days are not returned, and ones that are not 30 days old are returned ... using static fixtures this cannot be done (in a lazy way). So what I chose to do is mock the timezone.now function which django uses to get the datetime to use.

    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 ...   
    

    for mocking I use minimocktest

    0 讨论(0)
提交回复
热议问题