gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-03 17:59:42 24 4
gpt4 key购买 nike

所以我正在开发一个应用程序,在导入某些记录时,需要重新计算某些字段。为了防止每次检查都读取数据库,有一个缓存装饰器,因此在导入期间仅每 n 秒执行一次数据库读取。麻烦来自于构建测试用例。下面的代码确实有效,但它有一个丑陋的 sleep 。

# 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 仍然会在运行我的 tests.py 之前初始化模型,并且该函数仍然使用缓存装饰器而不是我的 lambda/noop 装饰器进行装饰。

编写此测试的最佳方法是什么,这样我就不用 sleep 了。我可以在运行导入之前设置装饰器的 ttl 吗?

最佳答案

您可以稍微更 retrofit 饰器类。

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,然后,嘿,快点!-)

关于python - 使用缓存装饰器在 Python 中运行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27913027/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com