Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用缓存装饰器在Python中运行单元测试_Python_Django_Unit Testing_Caching_Django Models - Fatal编程技术网

使用缓存装饰器在Python中运行单元测试

使用缓存装饰器在Python中运行单元测试,python,django,unit-testing,caching,django-models,Python,Django,Unit Testing,Caching,Django Models,因此,我正在开发一个应用程序,在导入某些记录时,需要重新计算某些字段。为了防止每次检查都读取数据库,有一个缓存装饰器,因此在导入期间,数据库读取仅每n秒执行一次。问题在于构建测试用例。下面的方法确实有效,但它有一个难看的睡眠 # The decorator I need to patch @cache_function_call(2.0) def _latest_term_modified(): return PrimaryTerm.objects.latest('object_mod

因此,我正在开发一个应用程序,在导入某些记录时,需要重新计算某些字段。为了防止每次检查都读取数据库,有一个缓存装饰器,因此在导入期间,数据库读取仅每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吗

您可以稍微更改一下decorator类

在模块级,在
decorators.py
中设置全局

BAILOUT = False
在您的decorator课程中,更改:

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.bailad=True,并且,嘿,presto!-)