【问题标题】:How do I freeze time and assert on a timestamp in a template?如何冻结时间并断言模板中的时间戳?
【发布时间】:2019-05-22 11:17:03
【问题描述】:

p1/urls.py:

from django.urls import path
from . import views
urlpatterns = [
    path('t1/', views.t1),
]

p1/views.py:

from django.shortcuts import render
def t1(request):
    return render(request, 'p1/t1.html')

p1/templates/p1/t1.html:

<?xml version="1.0" encoding="UTF-8"?>
<root timestamp="{% now 'Y-m-d H:i:s' %}">...</root>

p1/settings.py:

TIME_ZONE = 'Asia/Tokyo'
USE_TZ = True
INSTALLED_APPS = [
    ...
    'p1',
]

p1/tests.py:

from django.test import TestCase
from freezegun import freeze_time

class MyTestCase(TestCase):
    @freeze_time('2019-01-02 03:04:05')
    def test_freezegun(self):
        expected_response = '''
            <?xml version="1.0" encoding="UTF-8"?>
            <root timestamp="2019-01-02 03:04:05">...</root>
        '''
        response = self.client.get('/t1/')
        self.assertXMLEqual(expected_response, response.content.decode(response.charset))

那么,

$ ./manage.py test
Creating test database for alias 'default'...
F
======================================================================
FAIL: test_freezegun (p1.tests.MyTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/yuri/_/1/env/lib/python3.7/site-packages/freezegun/api.py", line 658, in wrapper
    result = func(*args, **kwargs)
  File "/home/yuri/_/1/p1/p1/tests.py", line 12, in test_freezegun
    self.assertXMLEqual(expected_response, response.content.decode('utf-8'))
  File "/home/yuri/_/1/env/lib/python3.7/site-packages/django/test/testcases.py", line 854, in assertXMLEqual
    self.fail(self._formatMessage(msg, standardMsg))
AssertionError: '\n            <?xml version="1.0" encoding="UTF-8"?>\n            <root timesta [truncated]... != '<?xml version="1.0" encoding="UTF-8"?>\n<root timestamp="2019-01-02 12:04:05">. [truncated]...
- 
-             <?xml version="1.0" encoding="UTF-8"?>
? ------------

+ <?xml version="1.0" encoding="UTF-8"?>
-             <root timestamp="2019-01-02 03:04:05">...</root>
? ------------                            ^^

+ <root timestamp="2019-01-02 12:04:05">...</root>
?                             ^^

-         

----------------------------------------------------------------------
Ran 1 test in 0.031s

FAILED (failures=1)
Destroying test database for alias 'default'...
System check identified no issues (0 silenced).

我做错了什么?将tz_offset 添加到freeze_time 没有帮助。

【问题讨论】:

  • 您是否尝试过检查 utc、datetime、django now、shell 中的值?我认为时区偏移应该有效。
  • tz_offset 添加到freeze_time 应该可以,“没有帮助”是什么意思?
  • 我只记得当我更改tz_offset 时,预期时间和实际时间都在不断变化。可能我对这一切将如何运作有一个错误的想法。

标签: python django django-unittest freezegun


【解决方案1】:

这里的事情是大多数时候 Django 将时间戳存储在UTC 中。并且仅在将data 呈现给user 时转换为本地时间。因此,我传递给 freeze_time 的时间被视为 UTC,但随后模板中的 now 将其转换为本地时间。因此,我必须在 expected_response (2019-01-02 12:04:05) 中指定当地时间,或者在“冻结时间”字符串 (2019-01-02 03:04:05 JST) 中指定时区,或者添加 tz_offset(JST 是 UTC+9h,所以tz_offset=-9)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-03
    • 2019-09-20
    • 2015-12-30
    • 2018-07-08
    相关资源
    最近更新 更多