如何模拟Django现在在所有应用程序功能中的功能

时间:2016-07-16 01:33:52

标签: python django unit-testing mocking

我试图模仿Django的now()函数,以欺骗我的应用程序中使用的时间。我可以轻松地在我的测试文件中模拟now()函数,但模拟替换似乎不会递归地渗透到我的应用程序函数中。这是我正在使用的代码:

# file - tests.py:

import datetime
import pytz
import mock

from django.test import TestCase

# this is the fake time I am using
TESTING_DJNOW = pytz.timezone('US/Central').localize(datetime.datetime(2016, 6, 14, 8, 0))


# This is the function that replaces django.utils.timezone.now()
def mocked_djnow():
    return TESTING_DJNOW

@mock.patch('django.utils.timezone.now', side_effect=mocked_djnow)
class ViewsTestCase(TestCase):
    fixtures = ['users.json', 'views_data.json'] # our initial test data

    def setUp(self):
        self.client = Client()
        self.client.login(username='fred', password='secret')

    def test_view(self, *args):
        from django.utils.timezone import now
        tm = now() # returns datetime.datetime(2016, 6, 14, 8, 0, 
                   # tzinfo=<DstTzInfo 'US/Central' CDT-1 day, 19:00:00 DST>)

        resp = self.client.get(reverse('myapp:viewfunc1'))



# file - myapp.views.py:

from django.utils.timezone import localtime, now

@login_required
def viewfunc1(request):
    # returns datetime.datetime(2016, 7, 16, 1, 11, 6, 964624, tzinfo=<UTC>)
    tm = now() # returns current datetime

是否可以在整个应用程序中修补像now()这样的Django函数?如果是这样,我做错了什么?还有其他建议吗?

1 个答案:

答案 0 :(得分:1)

我个人不喜欢因为不断的疼痛而使用嘲笑来约会。相反,我建议你试试FreezeGun。它具有您在测试中和任何地方所需的各种日期时间摆弄工具。

带有时区的文档示例:

from freezegun import freeze_time

@freeze_time("2012-01-14 03:21:34", tz_offset=-4)
def test():
    assert datetime.datetime.utcnow() == datetime.datetime(2012, 1, 14, 3, 21, 34)
    assert datetime.datetime.now() == datetime.datetime(2012, 1, 13, 23, 21, 34)

    # datetime.date.today() uses local time
    assert datetime.date.today() == datetime.date(2012, 1, 13)

它还具有很酷的功能,如手动刻度和上下文管理器。 lib大约有500行代码并写得非常好,所以你可以在一小时内从A到Z读取它,以了解它是如何工作的。