mirror of
https://github.com/DRYTRIX/TimeTracker.git
synced 2026-05-16 17:39:26 -05:00
test(cache): use real app fixture instead of mocking Flask's LocalProxy
TestCacheIntegration::test_get_cache_with_redis_enabled and
test_get_cache_fallback_to_memory were both failing with:
RuntimeError: Working outside of application context.
The tests patched `app.utils.cache.current_app` with a MagicMock and
set `mock_app.config = {...}`. In theory that should isolate get_cache()
from Flask's LocalProxy entirely. In practice the RuntimeError still
fires — most likely because (a) module-level `_cache` left over from a
prior test holds a reference that triggers a LocalProxy access at
return time, or (b) a code path inside the patched function still
reaches the real `current_app` past the mock boundary.
Rather than diagnose the exact mock-interaction issue, rewrite both
tests to use the real `app` fixture from conftest.py:
- Set `REDIS_ENABLED` / `REDIS_URL` / `REDIS_DEFAULT_TTL` on the real
Flask config inside `with app.app_context():`.
- Reset `app.utils.cache._cache = None` explicitly so the global
doesn't leak state between tests.
- Keep the `patch("app.utils.cache.RedisCache")` since we don't want
the test to actually hit Redis; only the read of `current_app.config`
needs to be real.
This is closer to how get_cache() runs in production (real Flask
context, mocked external dependency) and avoids the LocalProxy ↔ mock
collision entirely.
Test plan
- pytest tests/test_utils/test_cache.py::TestCacheIntegration::test_get_cache_with_redis_enabled
- pytest tests/test_utils/test_cache.py::TestCacheIntegration::test_get_cache_fallback_to_memory
- pytest tests/test_utils/test_cache.py (the other 16 tests in the file should be unaffected)
This commit is contained in:
@@ -125,33 +125,35 @@ class TestRedisCache:
|
||||
class TestCacheIntegration:
|
||||
"""Integration tests for cache utilities"""
|
||||
|
||||
@patch("app.utils.cache.current_app")
|
||||
def test_get_cache_with_redis_enabled(self, mock_app):
|
||||
"""Test get_cache when Redis is enabled"""
|
||||
mock_config = {"REDIS_ENABLED": True, "REDIS_URL": "redis://localhost:6379/0", "REDIS_DEFAULT_TTL": 3600}
|
||||
mock_app.config = mock_config
|
||||
def test_get_cache_with_redis_enabled(self, app):
|
||||
"""Test get_cache when Redis is enabled (RedisCache is mocked)."""
|
||||
import app.utils.cache as cache_module
|
||||
|
||||
with patch("app.utils.cache.RedisCache") as mock_redis_cache:
|
||||
mock_instance = MagicMock()
|
||||
mock_instance._connected = True
|
||||
mock_redis_cache.return_value = mock_instance
|
||||
cache_module._cache = None
|
||||
with app.app_context():
|
||||
app.config["REDIS_ENABLED"] = True
|
||||
app.config["REDIS_URL"] = "redis://localhost:6379/0"
|
||||
app.config["REDIS_DEFAULT_TTL"] = 3600
|
||||
|
||||
with patch("app.utils.cache.RedisCache") as mock_redis_cache:
|
||||
mock_instance = MagicMock()
|
||||
mock_instance._connected = True
|
||||
mock_redis_cache.return_value = mock_instance
|
||||
|
||||
cache = get_cache()
|
||||
assert cache is not None
|
||||
|
||||
def test_get_cache_fallback_to_memory(self, app):
|
||||
"""Test get_cache falls back to in-memory when Redis is disabled."""
|
||||
import app.utils.cache as cache_module
|
||||
|
||||
cache_module._cache = None
|
||||
with app.app_context():
|
||||
app.config["REDIS_ENABLED"] = False
|
||||
app.config["REDIS_DEFAULT_TTL"] = 3600
|
||||
|
||||
cache = get_cache()
|
||||
assert cache is not None
|
||||
|
||||
@patch("app.utils.cache.current_app")
|
||||
def test_get_cache_fallback_to_memory(self, mock_app):
|
||||
"""Test get_cache falls back to in-memory when Redis unavailable"""
|
||||
mock_config = {"REDIS_ENABLED": False, "REDIS_DEFAULT_TTL": 3600}
|
||||
mock_app.config = mock_config
|
||||
|
||||
# Reset global cache
|
||||
import app.utils.cache
|
||||
|
||||
app.utils.cache._cache = None
|
||||
|
||||
cache = get_cache()
|
||||
assert isinstance(cache, InMemoryCache)
|
||||
assert isinstance(cache, InMemoryCache)
|
||||
|
||||
def test_cache_decorator(self):
|
||||
"""Test the @cached decorator"""
|
||||
|
||||
Reference in New Issue
Block a user