python-dependency-injector icon indicating copy to clipboard operation
python-dependency-injector copied to clipboard

Question: Test DB setup using pyest fixture

Open MahmudulHassan5809 opened this issue 2 years ago • 0 comments
trafficstars

Hello
i am using this example : https://github.com/ets-labs/python-dependency-injector/tree/master/examples/miniapps/fastapi-sqlalchemy/webapp it is working fine .
Trying to use different database for testing . but can not setup a pytest fixture for override database url.

Any suggestion or any kind of example will be helpful . Thanks

actually i wan to do something link this :

@pytest.fixture(scope="function")
def override_db(app: FastAPI) -> Generator[None, None, None]:
    class MockDatabase(Database):
        def __init__(self, db_url: str) -> None:
            super().__init__(db_url)

        def create_database(self) -> None:
            pass

    with app.container.db.override(MockDatabase, db_url="your_test_db_url"):
        yield
My Database class :
from __future__ import annotations

import logging
from collections.abc import Iterator
from contextlib import AbstractContextManager, contextmanager

from sqlalchemy import create_engine, orm
from sqlalchemy.orm import Session, declarative_base

from src.core.config import settings

DATABASE_URL = f"oracle+oracledb://{settings.DATABASE_USERNAME}:{settings.DATABASE_PASSWORD}@{settings.DATABASE_HOSTNAME}"


logger = logging.getLogger(__name__)

Base = declarative_base()


class Database:
  def __init__(self, db_url: str) -> None:
      self._engine = create_engine(db_url, echo=True)
      self._session_factory = orm.scoped_session(
          orm.sessionmaker(
              autocommit=False,
              autoflush=False,
              bind=self._engine,
          ),
      )

  def create_database(self) -> None:
      Base.metadata.create_all(self._engine)

  @contextmanager
  def session(self) -> Iterator[AbstractContextManager[Session]]:
      session: Session = self._session_factory()
      try:
          yield session
      except Exception as e:
          logger.exception("Session rollback because of exception", e)
          session.rollback()
          raise
      finally:
          session.close()


My Dependency Injector 
from dependency_injector import containers, providers

from src.core.db.connector import DATABASE_URL, Database
from src.modules.auth.service import AuthService
from src.modules.users.models import User
from src.modules.users.repository import UserRepository
from src.modules.users.service import UserService


class Container(containers.DeclarativeContainer):
  wiring_config = containers.WiringConfiguration(
      modules=[
          "src.modules.users.controller",
          "src.modules.auth.controller",
      ]
  )

  db = providers.Singleton(Database, db_url=DATABASE_URL)

  user_repository = providers.Factory(
      UserRepository,
      model=User,
      session_factory=db.provided.session,
  )

  user_service = providers.Factory(
      UserService,
      user_repository=user_repository,
  )

  auth_service = providers.Factory(
      AuthService,
      user_repository=user_repository,
  )
  ```

MahmudulHassan5809 avatar Sep 25 '23 11:09 MahmudulHassan5809