I have a fastapi router file that has a function that calls a utility function in another file that interacts with GCS. I want to mock out the entire gcsutil.create_bucket in an unit test of institutions.py:
institutions.py
from google.cloud import storage
from ..gcsutil import generate_upload_signed_url, create_bucket, create_folders
# .... other imports
router = APIRouter(
tags=["institutions"],
)
@router.post("/institutions/", response_model=Institution)
def create_institution(
req: InstitutionCreationRequest,
current_user: Annotated[BaseUser, Depends()],
sql_session: Annotated[Session, Depends(get_session)],
) -> Any:
bucket_name = "FOO"
try:
# WANT TO MOCK OUT THE BELOW create_bucket
create_bucket(bucket_name)
except ValueError as e:
raise HTTPException(...SOME ERROR...)
return {}
gcsutil.py
from google.cloud import storage, storage_control_v2
from google.cloud.storage import Client
from typing import Any
def create_bucket(bucket_name: str) -> Any:
client = storage.Client()
bucket = client.bucket(bucket_name)
if bucket.exists():
raise ValueError(bucket_name + " already exists. Creation failed.")
bucket.storage_class = "STANDARD"
new_bucket = client.create_bucket(bucket, location="us")
return new_bucket
institutions_test.py
from fastapi.testclient import TestClient
import pytest
import unittest
from unittest import mock
from unittest.mock import Mock
from . import institutions
from ..main import app
@pytest.fixture(name="session")
def session_fixture():
# sets up databases
@pytest.fixture(name="client")
def client_fixture(session: sqlalchemy.orm.Session):
def get_session_override():
return session
app.include_router(institutions.router)
app.dependency_overrides[get_session] = get_session_override
client = TestClient(app)
yield client
app.dependency_overrides.clear()
mock.patch(institutions.__name__ + '.create_bucket', Mock(return_value=None))
def test_create_inst(mock_storage, client):
mock_gcs_client = mock_storage.Client.return_value
mock_bucket = Mock()
mock_bucket.blob.return_value.download_as_string.return_value = "foobar".encode('utf-8')
mock_gcs_client.bucket.return_value = mock_bucket
response = client.post("/institutions/12345")
assert response.status_code == 200
Based on @Patch decorator is not compatible with pytest fixture and How to mock using patch relative paths?
However I’m getting this error:
fixture 'mock_create_bucket' not found
> available fixtures: _session_faker, anyio_backend, anyio_backend_name, anyio_backend_options, cache, capfd, capfdbinary, caplog, capsys, capsysbinary, client, doctest_namespace, faker, monkeypatch, pytestconfig, record_property, record_testsuite_property, record_xml_attribute, recwarn, session, tmp_path, tmp_path_factory, tmpdir, tmpdir_factory
> use 'pytest --fixtures [testpath]' for help on them.