FastAPI单元测试中清除aiocache缓存失败的问题排查
问题分析与解决方案
可能的原因
多进程隔离:如果你的单元测试用了多进程运行(比如
pytest-xdist),API服务的内存缓存和测试进程的内存缓存是完全隔离的,测试里调用clear()只会清除当前测试进程的缓存,根本触不到API进程里的缓存,这是最常见的原因。缓存实例不统一:你通过
get_permissions.cache获取的缓存实例,可能和接口实际使用的不是同一个。aiocache的cached装饰器如果每次都用cache=Cache.MEMORY,可能会创建新的缓存实例,导致测试里拿到的实例和API用的不一致。异步执行问题:虽然你用了
await,但如果测试环境没有正确配置异步支持(比如没装pytest-asyncio或者没加@pytest.mark.asyncio装饰器),await不会真正执行,缓存自然清不掉。
解决办法
1. 解决多进程隔离问题
- 改用单进程运行测试:去掉
pytest-xdist的多进程参数(比如-n auto),用单进程执行测试。 - 换用共享缓存:把内存缓存换成Redis这类跨进程共享的缓存,这样测试和API进程操作的是同一个缓存实例,清除操作会生效。修改代码如下:
# 初始化Redis缓存 cache = Cache(Cache.REDIS, endpoint="localhost", port=6379, db=0) @router.get("/id/{user_id}/permissions") @cached(ttl=30, cache=cache) async def get_permissions(user_id: UUID4) -> list[Permissions]: # ... 接口实现
2. 统一缓存实例
提前在模块里定义全局缓存实例,不要在cached装饰器里直接创建:
# my_module.py from aiocache import Cache, cached from fastapi import APIRouter from uuid import UUID router = APIRouter() # 全局缓存实例 global_cache = Cache(Cache.MEMORY) @router.get("/id/{user_id}/permissions") @cached(ttl=30, cache=global_cache) async def get_permissions(user_id: UUID) -> list: # ... 接口逻辑,比如返回权限列表 return ["read", "write"]
测试时直接导入这个全局实例清除:
# test_module.py import pytest from my_module import global_cache @pytest.mark.asyncio async def test_clear_cache(): await global_cache.clear() # 后续执行接口请求,就能拿到最新数据
3. 精准删除单个缓存键(而非全量清除)
如果不想全量清除缓存,可以通过生成对应的缓存键来删除指定用户的权限缓存:
import pytest from uuid import UUID from aiocache.keys import get_cache_key from my_module import get_permissions, global_cache @pytest.mark.asyncio async def test_delete_specific_permission_cache(): test_user_id = UUID("123e4567-e89b-12d3-a456-426614174000") # 生成缓存键 cache_key = await get_cache_key(get_permissions, args=(test_user_id,), kwargs={}) # 删除指定键 await global_cache.delete(cache_key)
4. 确认异步测试环境配置
确保测试文件里的异步函数加了@pytest.mark.asyncio装饰器,并且已经安装了pytest-asyncio依赖:
pip install pytest-asyncio
内容的提问来源于stack exchange,提问作者DUDANF
相关产品推荐
相关产品推荐

