Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to mock get_redis function with pytest

I am using fakeredis and pytest on an application

My get_redis function on file app/helpers/providers.py:

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)

Then I use it on my code, located at 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

Then on my tests I have the following:

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

The test fails because it tries to use the real redis, which raises an exception.

What I am doing wrong? I have another test that works fine.

like image 579
Rodrigo Avatar asked Jan 19 '26 12:01

Rodrigo


1 Answers

This solved my issue

@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)
like image 135
Rodrigo Avatar answered Jan 22 '26 01:01

Rodrigo