fedest
fedest

Reputation: 1366

Pytest mocker not mocking

I have the following structure for my code which is a fastapi app:

/repo
  /src
    main.app
  /routes
    /resource
      resource.py
  /repository
    repository.py
  /tests
    /routes
      /resource
        resource_test.py

/src/routes/resource/resource.py

def get_repository() -> Repository:
   return repository

RepositoryDep = Annotated[Repository, Depends(get_repository)]


router = APIRouter()

@router.get("/")
def list(repo: RepositoryDep) -> list[Alumno]:
    return repo.list()

/src/repository/repository.py

class Repository:
  ...

repository = Repository()

Then I have some tests for my router like this tests/routes/resource/resource.py


client = TestClient(app)

def test_get_resources(mocker) -> None:
    mock_repo = MagicMock(Repository)
    mock_repo.list.return_value = [
        Resource(id=1, name="Something", age=20),
        Resource(id=2, name="Something2", age=22)
    ]

    mocker.patch('src.routes.resource.resource.get_repository', return_value=mock_repo)
    response = client.get(
        "/resources/",
    )

    assert response.status_code == 200
    content = response.json()
    assert len(content) == 2

But this tests fails, the repository used (checked by debugging) is not the mock I set up, it's the real object.

Why is it not mocking?

Upvotes: -1

Views: 19

Answers (1)

M.O.
M.O.

Reputation: 3011

The reason it doesn't work is that RepositoryDep is created at load time, so it gets its reference to get_repository when the application starts, long before your test actually runs.

The solution is to use FastAPI's dependency_overrides, which are designed for this exact purpose:

def test_get_resources(mocker) -> None:
    mock_repo = MagicMock(Repository)
    mock_repo.list.return_value = [
        Resource(id=1, name="Something", age=20),
        Resource(id=2, name="Something2", age=22)
    ]

    client.dependency_overrides = { get_repository: lambda: mock_repo }
    response = client.get(
        "/resources/",
    )

    assert response.status_code == 200
    content = response.json()
    assert len(content) == 2

    client.dependency_overrides = {}

Upvotes: 0

Related Questions