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))
Then,
$ ./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).
What am I doing wrong? Adding tz_offset
to freeze_time
doesn't help.
The thing here is that most of the time Django stores timestamps in UTC. And converts to local time only when presenting data to the user. So, the time I pass to freeze_time
is treated as UTC, but then now
in the template converts it to local time. As such, I've got to either specify local time in expected_response
(2019-01-02 12:04:05
), or time zone in "freeze time" string (2019-01-02 03:04:05 JST
), or add tz_offset
(JST is UTC+9h, so tz_offset=-9
).