浏览代码

Fixed #23792 -- Added test.utils.freeze_time() context manager.

Thomas Chaumeny 10 年之前
父节点
当前提交
994d6137a2
共有 3 个文件被更改,包括 25 次插入21 次删除
  1. 17 0
      django/test/utils.py
  2. 3 8
      tests/signed_cookies_tests/tests.py
  3. 5 13
      tests/signing/tests.py

+ 17 - 0
django/test/utils.py

@@ -555,3 +555,20 @@ def reset_warning_registry():
     for mod in sys.modules.values():
         if hasattr(mod, key):
             getattr(mod, key).clear()
+
+
+@contextmanager
+def freeze_time(t):
+    """
+    Context manager to temporarily freeze time.time(). This temporarily
+    modifies the time function of the time module. Modules which import the
+    time function directly (e.g. `from time import time`) won't be affected
+    This isn't meant as a public API, but helps reduce some repetitive code in
+    Django's test suite.
+    """
+    _real_time = time.time
+    time.time = lambda: t
+    try:
+        yield
+    finally:
+        time.time = _real_time

+ 3 - 8
tests/signed_cookies_tests/tests.py

@@ -1,10 +1,9 @@
 from __future__ import unicode_literals
 
-import time
-
 from django.core import signing
 from django.http import HttpRequest, HttpResponse
 from django.test import TestCase, override_settings
+from django.test.utils import freeze_time
 
 
 class SignedCookieTest(TestCase):
@@ -46,22 +45,18 @@ class SignedCookieTest(TestCase):
 
     def test_max_age_argument(self):
         value = 'hello'
-        _time = time.time
-        time.time = lambda: 123456789
-        try:
+        with freeze_time(123456789):
             response = HttpResponse()
             response.set_signed_cookie('c', value)
             request = HttpRequest()
             request.COOKIES['c'] = response.cookies['c'].value
             self.assertEqual(request.get_signed_cookie('c'), value)
 
-            time.time = lambda: 123456800
+        with freeze_time(123456800):
             self.assertEqual(request.get_signed_cookie('c', max_age=12), value)
             self.assertEqual(request.get_signed_cookie('c', max_age=11), value)
             self.assertRaises(signing.SignatureExpired,
                 request.get_signed_cookie, 'c', max_age=10)
-        finally:
-            time.time = _time
 
     @override_settings(SECRET_KEY=b'\xe7')
     def test_signed_cookies_with_binary_key(self):

+ 5 - 13
tests/signing/tests.py

@@ -1,10 +1,10 @@
 from __future__ import unicode_literals
 
 import datetime
-import time
 
 from django.core import signing
 from django.test import TestCase
+from django.test.utils import freeze_time
 from django.utils.encoding import force_str
 from django.utils import six
 
@@ -117,23 +117,15 @@ class TestTimestampSigner(TestCase):
 
     def test_timestamp_signer(self):
         value = 'hello'
-        _time = time.time
-        time.time = lambda: 123456789
-        try:
+        with freeze_time(123456789):
             signer = signing.TimestampSigner('predictable-key')
             ts = signer.sign(value)
             self.assertNotEqual(ts,
                 signing.Signer('predictable-key').sign(value))
-
             self.assertEqual(signer.unsign(ts), value)
-            time.time = lambda: 123456800
-            self.assertEqual(signer.unsign(ts, max_age=13), value)
+
+        with freeze_time(123456800):
             self.assertEqual(signer.unsign(ts, max_age=12), value)
             # max_age parameter can also accept a datetime.timedelta object
             self.assertEqual(signer.unsign(ts, max_age=datetime.timedelta(seconds=11)), value)
-            self.assertRaises(
-                signing.SignatureExpired, signer.unsign, ts, max_age=10)
-            with self.assertRaises(signing.SignatureExpired):
-                self.assertEqual(signer.unsign(ts, max_age=datetime.timedelta(seconds=10)), value)
-        finally:
-            time.time = _time
+            self.assertRaises(signing.SignatureExpired, signer.unsign, ts, max_age=10)