-
-
Notifications
You must be signed in to change notification settings - Fork 337
-
Hi there,
Firstly just wanted to say thanks for taking the time to share an example of how to hook this up using FastAPI, it's been extremely useful and a great starting point.
I wanted to take the testing aspect one step further and run some full end-to-end tests that actually persist to a database (sqlite) to also check that everything was working as expected (even the repositories). I modified the app creation to more or less resemble this:
# container.py class Container(containers.DeclarativeContainer): wiring_config = containers.WiringConfiguration( modules=["app.routers.routerA"] ) config = providers.Configuration(yaml_files=["config.yml"]) db = providers.Singleton(Database, db_url=config.db.url) A_repo = providers.Factory( RepoA, session_factory=db.provided.session ) # server.py def create_server(container): app = FastAPI() app.container = container app.include_router(routerA) return app
I've then modified my tests to look like:
from app.server import create_server class TestContainer(containers.DeclarativeContainer): wiring_config = containers.WiringConfiguration( modules=["app.routers.routerA"] ) config = providers.Configuration(yaml_files=["test.config.yml"]) db = providers.Singleton(Database, db_url=config.db.url) A_repo = providers.Factory( RepoA, session_factory=db.provided.session ) container = TestContainer() app = create_server(container) @pytest.fixture def client(): yield TestClient(app)
My issue now is that in one of my tests where I'm testing to see if an exception is raised correctly, instead of catching the side-effect and being able to assert it's how I expect it's breaking because of the exception being raised. It looks like such:
async def test_get_by_id_err(client): repository_mock = mock.Mock(spec=RepoA) repository_mock.get_by_id.side_effect = ResourceNotFound( "Resource could not be found. Please provide a valid ID.", ) with app.container.A_repo.override(repository_mock): request = client.get("/resource/notexistent") response = request.json() assert request.status_code == 404
This just results in a stacktrace for the above side_effect
being thrown in the route. However when not making the container a parameter to the app creation i.e.
def create_server(): app = FastAPI() container = Container() app.container = container app.include_router(routerA) return app
this test works absolutely fine. Which leads me to believe it's got something to do how the mock is behaving with the Container. I'm relatively new to testing with DI and Python so I might just be doing silly here but I can't understand why one would work and the other wouldn't. Would you have any insight into why this might be happening? (Hope everything there is clear in what I mean, happy to create a small sample repo if it doesn't make sense) Any help would very much be appreciated!
Beta Was this translation helpful? Give feedback.