因此,我正在开发一个应用程序,该应用程序在导入某些记录时需要重新计算某些字段。为防止每次检查都读取数据库,有一个缓存装饰器,因此在导入期间每n秒仅执行一次数据库读取。麻烦来自构建测试用例。下面的方法确实有效,但是其中有一个丑陋的睡眠。
# 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
但是,即使在文件的顶部,django仍会在运行my之前初始化模型,tests.py
并且该函数仍会使用缓存装饰器(而不是我的lambda / noop)装饰。
编写此测试的最佳方法是什么,这样我就不用睡了。我可以在以某种方式运行导入之前设置装饰器的ttl吗?
您可以稍微更改装饰器类。
在模块级别decorators.py
设置全局
BAILOUT = False
在装饰器类中,更改:
def __call__(self, func):
@wraps(func)
def inner():
now = time.time()
if BAILOUT or now > self.timestamp + self.ttl:
self.cached_result = func()
self.timestamp = now
return self.cached_result
return inner
然后在您的测试集中decorators.BAILOUT = True
,然后,嘿!!)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句