【发布时间】:2021-03-20 20:24:33
【问题描述】:
如何使用 cachetools 在 Python 单元测试中模拟缓存值?我写了一个名为 cache_controller 的装饰器。我有正当理由不使用 Cachetools 的装饰器。 当我在编写测试代码时尝试模拟 TTLCache 对象时,我无法模拟它。会是什么原因?
src/helpers/cache.py
from cachetools import TTLCache
total_cache = TTLCache(maxsize=1024, ttl=600)
src/wrappers/cache_controller.py
from functools import wraps
def cache_controller(cache, cache_args: tuple):
"""
:return: wrapper
"""
def decorator(func):
@wraps(func)
def wrapper(self, *args, **kwargs):
print("Cache in CACHE CONROLLER:", cache)
cache_key = tuple([kwargs[arg] for arg in cache_args])
print("Cache key in CACHE CONROLLER:", cache_key)
cached_value = cache.get(cache_key)
print("Cache value in CACHE CONROLLER:", cached_value)
if cached_value:
print(f"{self.__class__.__name__} : {cache_key} : from Local Cache : {cached_value}")
return cached_value
result = func(self, *args, **kwargs)
cache.update({cache_key: result})
print(f"{self.__class__.__name__} : {cache_key} : Updated to Local Cache : {result}")
return result
return wrapper
return decorator
src.run.py
from .wrappers.cache_controller import cache_controller
from .helpers.cache import total_cache
class ExampleClass(object):
@cache_controller(
cache=total_cache,
cache_args=("a", "b")
)
def example_method(self, a: int, b: int):
return a+b
*test/test_cache_controller.py
import unittest
from cachetools.ttl import TTLCache
from src.run import ExampleClass
from unittest import TestCase, mock
class TestCacheController(TestCase):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def setUp(self):
self.fake_cache = TTLCache(maxsize=10, ttl=3600)
self.fake_cache.__setitem__((5, 6), 1)
self._class = ExampleClass()
def tearDown(self):
self._class = None
@ mock.patch("src.run.total_cache")
def test_if_cache_filled(self, mock_total_cache):
mock_total_cache.return_value = self.fake_cache
result = self._class.example_method(a=5, b=6)
func_expected = 11
cache_expected = 1
print("Result:", result)
self.assertEqual(result, cache_expected)
if __name__ == '__main__':
unittest.main()
.. 并运行测试代码
cachetools-mock ❯ python -m test.test_cache_controller
Cache in CACHE CONROLLER: TTLCache([], maxsize=1024, currsize=0)
Cache key in CACHE CONROLLER: (5, 6)
Cache value in CACHE CONROLLER: None
ExampleClass : (5, 6) : Updated to Local Cache : 11
Result: 11
F
======================================================================
FAIL: test_if_cache_filled (__main__.TestCacheController)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/sumeyyeozkaynak/.pyenv/versions/3.7.5/lib/python3.7/unittest/mock.py", line 1255, in patched
return func(*args, **keywargs)
File "/Users/sumeyyeozkaynak/Desktop/.optiwisdom/workspace/cachetools-mock/test/test_cache_controller.py", line 28, in test_if_cache_filled
self.assertEqual(result, cache_expected)
AssertionError: 11 != 1
----------------------------------------------------------------------
Ran 1 test in 0.004s
FAILED (failures=1)
【问题讨论】:
标签: caching mocking wrapper python-unittest python-decorators