无法使用pytest模拟get_redis函数
我在一个应用程序中使用fakeredis和pytest。
我在文件 app/helpers/providers.py
中的get_redis函数是这样的:
from redis import ConnectionPool, Redis
redis_pool = None
def get_redis() -> Redis:
global redis_pool
if redis_pool is None:
redis_pool = ConnectionPool()
return Redis.from_pool(redis_pool)
然后我在我的代码中使用它,代码位于 app/endpoints/secrets.py
:
from app.helpers.providers import get_redis
@router.get("/secrets/{secret_id}")
async def get_secret(
request: Request,
secret_id: UUID,
credentials: Annotated[HTTPBasicCredentials, Depends(security)],
redis: Redis = Depends(get_redis),
):
with redis.pipeline() as pipe: # I use redis from get_redis here
pipe.get(key)
pipe.delete(key)
results = pipe.execute()
return results # just to simplify
接着在我的测试中,我有以下内容:
import sys
from unittest.mock import patch
import fakeredis
import pytest
from fastapi import HTTPException, status
from fastapi.exceptions import RequestValidationError
from fastapi.testclient import TestClient
@pytest.fixture
def fake_redis():
return fakeredis.FakeStrictRedis()
@pytest.fixture(autouse=True)
def mock_redis_dependencies(fake_redis):
with patch('app.endpoints.secrets.get_redis', return_value=fake_redis):
yield
sys.path.append(".")
from app.endpoints.secrets import router
def test_secret_not_found(fake_redis):
client = TestClient(router)
with pytest.raises(HTTPException) as exc:
client.get(
"/api/secrets/aaaaaaaa-bbbb-4ccc-aaaa-eeeeeeeeeef1",
auth=("admin", "admin"),
)
assert exc.value.status_code == status.HTTP_404_NOT_FOUND
这个测试失败了,因为它试图使用真实的redis,这导致了一个异常。
我哪里做错了?我还有另一个测试运行得很好。
1 个回答
1
这个解决了我的问题
@pytest.fixture(autouse=True)
def mock_redis_dependencies(monkeypatch, fake_redis):
monkeypatch.setattr("app.decorators.rate_limit.redis", fake_redis)
monkeypatch.setattr("app.endpoints.secrets.redis", fake_redis)