【发布时间】:2017-12-02 21:52:39
【问题描述】:
使用 django-cacheops,我想测试我的视图是否按照我的预期被缓存。在我的测试用例中,我将 cacheops cache_read 信号连接到一个处理程序,该处理程序应该为命中或未命中增加缓存中的一个值。但是,信号永远不会被触发。有谁知道在测试用例中连接 django 信号处理程序的正确方法,纯粹用于该测试用例?
这是我目前所拥有的
from cacheops.signals import cache_read
cache.set('test_cache_hits', 0)
cache.set('test_cache_misses', 0)
def cache_log(sender, func, hit, **kwargs):
# never called
if hit:
cache.incr('test_cache_hits')
else:
cache.incr('test_cache_misses')
class BootstrapTests(TestCase):
@classmethod
def setUpClass(cls):
super(BootstrapTests, cls).setUpClass()
cache_read.connect(cache_log)
assert cache_read.has_listeners()
def test_something_that_should_fill_and_retrieve_cache(self):
....
hits = cache.get('test_cache_hits') # always 0
我也尝试在模块级别连接信号处理程序,并在常规测试用例setUp 方法中,都具有相同的结果。
编辑:
这是我的实际测试代码,以及我正在测试的对象。我正在使用 cached_as 装饰器来缓存一个函数。此测试当前失败。
boostrap.py
class BootstrapData(object):
def __init__(self, app, person=None):
self.app = app
def get_homepage_dict(self, context={}):
url_name = self.app.url_name
@cached_as(App.objects.filter(url_name=url_name), extra=context)
def _get_homepage_dict():
if self.app.homepage is None:
return None
concrete_module_class = MODULE_MAPPING[self.app.homepage.type]
serializer_class_name = f'{concrete_module_class.__name__}Serializer'
serializer_class = getattr(api.serializers, serializer_class_name)
concrete_module = concrete_module_class.objects.get(module=self.app.homepage)
serializer = serializer_class(context=context)
key = concrete_module_class.__name__
return {
key: serializer.to_representation(instance=concrete_module)
}
return _get_homepage_dict()
test_bootstrap.py
class BootstrapDataTest(TestCase):
def setUp(self):
super(BootstrapDataTest, self).setUp()
def set_signal(signal=None, **kwargs):
self.signal_calls.append(kwargs)
self.signal_calls = []
cache_read.connect(set_signal, dispatch_uid=1, weak=False)
self.app = self.setup_basic_app() # creates an 'App' model and saves it
def tearDown(self):
cache_read.disconnect(dispatch_uid=1)
def test_boostrap_data_is_cached(self):
obj = BootstrapData(self.app)
obj.get_homepage_dict()
# fails, self.signal_calls == []
self.assertEqual(self.signal_calls, [{'sender': App, 'func': None, 'hit': False }])
self.signal_calls = []
obj.get_homepage_dict()
self.assertEqual(self.signal_calls, [{'sender': App, 'func': None, 'hit': True}])
【问题讨论】:
-
您确定测试会触发
cache_read信号吗?不仅仅是任何缓存读取都会触发 cacheopscache_read信号。 github.com/Suor/django-cacheops/blob/master/cacheops/query.py 同样在 cachops 包中,他们有一个测试示例,他们在setUp方法中连接信号。 github.com/Suor/django-cacheops/blob/… -
我可能是错的,但 django-cacheops 旨在缓存查询集而不是常规键。因此,
cache_read信号将不会被调用,因为您尝试获取的值不是查询集。 -
您可能不会发出 cacheops 请求或永远不会被点击。你应该提供你的测试代码。
-
感谢 ARJMP - 测试代码看起来是一个很好的尝试途径。 @Suor - 我只是在为缓存操作注册的模型上进行定期保存和检索。手动测试时,很明显 cacheops 正在缓存它们,但我想确定一下。
标签: python django unit-testing caching signals