У меня есть несколько тестов для функций, которые используют кэш, например:
Функция:
@retry(stop=stop_after_attempt(3))
@cache.cached(timeout=60, key_prefix='resouce_group_list')
def get_azure_resource_groups():
data = []
resource_client = get_azure_resource_client()
for item in resource_client.resource_groups.list():
data.append(item)
return data
Тест:
@patch("dev_maintenance.machines.get_azure_resource_client")
def test_get_azure_list_rg(get_azure_resource_client):
cache.clear()
data = []
with app.app_context():
ret = get_azure_resource_groups()
get_azure_resource_client.assert_called_once()
expected = get_azure_resource_client.return_value.resource_groups.list.return_value
assert len(get_azure_resource_client.return_value.method_calls) == 1
for item in expected:
data.append(item)
assert ret == data
cache.clear()
Вышеприведенный тест работает нормально, он проходит, ошибок нет, и тест использует кеш.
Но у меня есть другие тесты, и декоратор здесь не имеет значения, он выдаст ту же ошибку, если я изменю декоратор на @cache.cache
:
Функция:
@retry(stop=stop_after_attempt(3))
@cache.memoize(60)
def get_azure_machine_info(rg_name, machine_name, expand="instanceView"):
try:
compute_client = get_azure_compute_client()
return compute_client.virtual_machines.get(rg_name, machine_name, expand=expand)
except CloudError:
return None
Тест:
@patch("dev_maintenance.machines.get_azure_compute_client")
def test_get_azure_machine_info (get_azure_compute_client):
cache.delete_memoized(get_azure_machine_info)
with app.app_context():
ret = get_azure_machine_info("rg1", "m1")
print(ret)
get_azure_compute_client.assert_called_once()
assert len(get_azure_compute_client.return_value.method_calls) == 1
assert (
ret == get_azure_compute_client.return_value.virtual_machines.get.return_value
)
get_azure_compute_client.return_value.virtual_machines.get.assert_called_once_with(
"rg1", "m1", expand="instanceView"
)
cache.delete_memoized(get_azure_machine_info)
Теперь здесь тест не пройден с ошибкой в этой строке ret = get_azure_machine_info("rg1", "m1")
:
value = None, from_value = PicklingError("Can't pickle <class 'unittest.mock.MagicMock'>: it's not the same object as unittest.mock.MagicMock")
> ???
E tenacity.RetryError: RetryError[<Future at 0x105c7c3d0 state=finished raised PicklingError>]
<string>:3: RetryError
Я попытался смоделировать кеш, передавая оформитель патча, например:
@patch("dev_maintenance.machines.cache") or @patch("dev_maintenance.cache")
Я попытался установить для CACHE_TYPE значение null в тестовом примере, создать экземпляр объекта кэша и передать конфигурацию:
cache = Cache()
cache.init_app(app, config={"CACHE_TYPE": "redis"})
но безуспешно, какая-нибудь помощь?