I'm working on a Python project where I use diskcache.Cache.memoize for caching. I want to write unit tests for my code, and I'm having trouble figuring out how to properly mock diskcache.Cache.memoize using pytest without being delayed in my mocks.
Here's a simplified version of my module:
# my_module.py
import diskcache
cache = diskcache.Cache('/path/to/my/local/cache')
@cache.memoize(expire=3600)
def expensive_function(argument):
# Expensive calculation here
return result
I want to write unit tests for expensive_function where I can test the caching behavior on and off via pytest.
I have mocked diskcache.Cache in conftest.py like so:
# conftest.py
import pytest
import unittest.mock
import diskcach
class MockCache:
def __init__(self, *args, **kwargs):
pass
def __call__(self, fun, *args, **kwargs):
return fun
def memoize(fun, *args, **kwargs):
return fun
@pytest.fixture(autouse=True)
def default_mock_memoize(monkeypatch, pytestconfig):
if not pytestconfig.getoption("--cache"):
monkeypatch.setattr(diskcache, "Cache", MockCache)
def pytest_addoption(parser):
parser.addoption(
"--cache",
action="store_true",
default=False,
help=(
"Enable caching for tests. Careful: This will disable the test coverage "
"of the cached code if the return value is in cache."
),
)
This works technically but is too late since it leaves the decorated expensive_function in the hands of the unmocked diskcache.Cache.
How can I achieve that diskcache.Cache is mocked before collection?
Thanks in advance for your help!