Итак, я работаю над приложением, которое при импорте определенных записей требует, чтобы некоторые поля были пересчитаны. Чтобы предотвратить чтение базы данных для каждой проверки, есть декодер кеширования, поэтому чтение базы данных выполняется только один раз каждые n секунд во время импорта. Проблема заключается в создании тестовых примеров. Следующее работает, но в нем есть уродливый сон.Выполнение модульных тестов в Python с помощью декоратора кеширования
# The decorator I need to patch
@cache_function_call(2.0)
def _latest_term_modified():
return PrimaryTerm.objects.latest('object_modified').object_modified
# The 2.0 sets the TTL of the decorator. So I need to switch out
# self.ttl for this decorated function before
# this test. Right now I'm just using a sleep, which works
@mock.patch.object(models.Student, 'update_anniversary')
def test_import_on_term_update(self, mock_update):
self._import_student()
latest_term = self._latest_term_mod()
latest_term.save()
time.sleep(3)
self._import_student()
self.assertEqual(mock_update.call_count, 2)
Сам декоратора выглядит следующим образом:
class cache_function_call(object):
"""Cache an argument-less function call for 'ttl' seconds."""
def __init__(self, ttl):
self.cached_result = None
self.timestamp = 0
self.ttl = ttl
def __call__(self, func):
@wraps(func)
def inner():
now = time.time()
if now > self.timestamp + self.ttl:
self.cached_result = func()
self.timestamp = now
return self.cached_result
return inner
Я попытался установить декоратор до импорта моделей:
decorators.cache_function_call = lambda x : x
import models
Но даже в верхней части file, django по-прежнему инициализирует модели перед запуском моего tests.py
, и функция по-прежнему украшена декодером кеширования вместо моего lambda/noop.
Каков наилучший способ написать этот тест, чтобы я не спал. Могу ли я установить ttl декоратора перед запуском моего импорта?