I'm using:
Python 3.9.13
pytest==7.2.0
pytest-mock==3.10.0
Flask==2.2.2
Flask-Caching==2.0.1
This is my class being tested:
@dataclass(frozen=True)
class NominationData:
title: str
url: str
is_approved: bool
articles: list[ArticleData]
hooks: list[HookData]
@staticmethod
@cache.memoize(timeout=30)
def from_nomination(nomination):
"""Construct a NominationData from a dyk_tools.Nomination"""
return NominationData(
nomination.title(),
nomination.url(),
nomination.is_approved(),
[ArticleData.from_article(a) for a in nomination.articles()],
[HookData.from_hook(h) for h in nomination.hooks()],
)
I've got a unit test for NominationData.from_nomination()
which previously worked in a non-memoized version. Now that I've added the @cache.memoize()
decoration, the test crashes in flask_caching/__init__.py:870
with AttributeError: 'Cache' object has no attribute 'app'
. It's obvious what the problem is: I don't have a valid application context in flask.current_app
. The question is, what's the best way to fix that?
One possibility would be to patch flask.current_app with a mock AppContext
, but I'm hesitant to go down that path. Another possibility would be to split out the memoization into a distinct shim:
@staticmethod
@cache.memoize(timeout=30)
def from_nomination(nomination):
return inner_from_nomination(nomination)
and then just call inner_from_nomination()
in my unit test. That should work, but just feels wrong. Or maybe there's some cleaner way entirely? How would you do this?
Oh, I get it. I need to change my unit test to call the .uncached function directly:
https://flask-caching.readthedocs.io/en/latest/api.html#flask_caching.Cache.memoize