Piszę tutaj test funkcjonalny, aby sprawdzić, czy moje ograniczanie API działa zgodnie z oczekiwaniami (będzie odpoczywać na początku każdego miesiąca).Problem z szyderstwem w teście django: czas wydaje się nie być zamrożony za pomocą freezegun
Testowanie Klasa:
class ApiThrottlingTest(ThrottlingBaseTest):
def test_throttling_purchaser_case(self):
now = datetime.datetime(year=2015, month=1, day=10, hour=6, minute=6, second=3)
last_day_of_current_month = datetime.datetime(year=2015, month=1, day=31, hour=23, minute=59, second=59)
first_day_of_next_month = datetime.datetime(year=2015, month=2, day=1, hour=0, minute=0, second=0)
with freeze_time(now) as frozen_datetime:
for i in xrange(3):
resp = self._project_details_request()
self.assertEqual(resp.status_code, 200)
resp = self._project_details_request()
self.assertEqual(resp.status_code, 429)
frozen_datetime.move_to(last_day_of_current_month)
resp = self._project_details_request()
# the test fails at this level
self.assertEqual(resp.status_code, 429)
frozen_datetime.move_to(first_day_of_next_month)
resp = self._project_details_request()
self.assertEqual(resp.status_code, 200)
Test działa prawidłowo gdy: last_day_of_current_month = datetime.datetime(... second=0)
ale nie powiedzie się, jeśli: last_day_of_current_month = datetime.datetime(... second=59)
Po debugowanie wydaje się, że moduł time
stosowanych w DjangoRestFramework throttling.UserRateThrottle
w jakiś sposób daje wartość, która zawsze wyprzedza czas fronzen w moim teście, który wynosi ca używając precyzyjnego wydania o kilku sekundach.
podstawie FreezeGun Doctime.time()
powinny być również mrożone:
Once the decorator or context manager have been invoked, all calls to datetime.datetime.now(), datetime.datetime.utcnow(), datetime.date.today(), time.time(), time.localtime(), time.gmtime(), and time.strftime() will return the time that has been frozen.
Ale wygląda na to im mój przypadek time.time
wykonuje poprawnie czas rozpoczęcia wyśmiewali datetime ale potem zmieniają się w czasie, który nie ma, to się tego spodziewać zamrożone do czasu ręcznego przekazania dalej.
Próbowałem wyśmiać time.time
używany w UserRateThrottle
oddzielnie przy użyciu modułu mock
, ale nadal nie rozwiązałem problemu.
----> Jakiś pomysł, jaki może być problem i jak można go rozwiązać?
test Fail: (po raz jest przekazywany do ostatniego dnia miesiąca: linii 14)
self.assertEqual(resp.status_code, 429)
AssertionError: 200 != 429
Kod źródłowy klasy DRF:
class SimpleRateThrottle(BaseThrottle):
...
cache = default_cache
timer = time.time
cache_format = 'throttle_%(scope)s_%(ident)s'
def __init__(self):
....
def allow_request(self, request, view):
...
self.now = self.timer() # here timer() returns unexpected value in test
....
Jak mogę zmienić to za pomocą FreezeGun !? W rzeczywistości pomyślałem o tym i próbowałem wyśmiać zwróconą wartość funkcji modułu używanej przez 'SimpleRateThrottle' ręcznie przy użyciu łatki małpy przy użyciu modułu python' mock', ale nadal mam ten sam problem !!! – DhiaTN
Przepraszam, uświadomiłem sobie, że po napisałem odpowiedź. Teraz jest edytowane z tym, jak to zrobić. – Linovia
Dzięki, ale nadal masz ten sam problem. – DhiaTN