Skip to content

Instantly share code, notes, and snippets.

@daaniam
Created March 31, 2023 23:37
Show Gist options
  • Save daaniam/4ea14e2e57a6957f7af410f54d1cfc7a to your computer and use it in GitHub Desktop.
Save daaniam/4ea14e2e57a6957f7af410f54d1cfc7a to your computer and use it in GitHub Desktop.
FastAPI: Pydantic's BaseSettings injection for pytest

FastAPI: Pydantic's BaseSettings injection for pytest


There are a few options how to change app config for tests. According to FastAPI docs, it's recommended to use `dependency_overrides`, but there might be a case where we need to change the entire app settings (using Pydantic's BaseSettings here).

config.py

[...code ommited...]

settings = Settings()  # Read from environment


@lru_cache()
def get_config() -> Settings:
    """Return cached settings object.

    Returns:
        Settings object.
    """

    return settings

conftest.py

Import module and some settings to be injected

import app.config as conf
from app.config import settings, Settings, Postgres, Bucket0

Create new configuration obejct(s)

# Change database settings for testing. This will ensure, that
# tests won't be run with the default database settings.
# If needed, this can be overridden in .env.test file which has
# a higher precedence.

test_database = Postgres(
    host="postgres",  # docker-compose
    port=5432,
    username="testuser",
    password="testpassword",
    database_name="testdb",
)

# As for now, Google doesn't offer local emulator for the Cloud Storage Bucket.
test_bucket = Bucket0(name="test_bucket")

Override Settings() with TestSettings()

class TestSettings(Settings):
    postgres = test_database
    bucket0 = test_bucket

    class Config:
        """Pydantic configuration meta-class."""

        env_file = ".env.test"

Re-assign the "settings" variable within conf file with TestSettings

conf.settings = TestSettings()

Import app -> TestClinet(app)

# IMPORTANT: Import has to happen after "app.config.settings" has been re-assigned with TestSettings()
from app.main import app  # noqa
@mreilaender
Copy link

Thank u very much for this!!

It's very weird though that this is such a pain in the a**

@OleksandrZhydyk
Copy link

Thanks a lot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment