Skip to content

Commit

Permalink
Merge pull request #30 from reagento/feature/real_world_tests
Browse files Browse the repository at this point in the history
Real world example tests
  • Loading branch information
Tishka17 authored Feb 7, 2024
2 parents c33f487 + 0a9b575 commit 385756b
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 6 deletions.
6 changes: 5 additions & 1 deletion examples/real_world/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,8 @@ Talking about _lifetime_ of objects we can say that:
│ ┌─────────────────┐ │
└─────►Products gateway ├─►───┘
└─────────────────┘
```
```

In production our frameworks enter scopes for us. But for tests it is often omitted by authors of frameworks.
* For fastapi or other asgi application you should use `asgi_lifespan.LifespanManager`
* For aiogram do not forget to trigger `dp.emit_startup()` event
10 changes: 7 additions & 3 deletions examples/real_world/main_web.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,21 @@
from myapp.presentation_web import router


def create_fastapi_app() -> FastAPI:
app = FastAPI()
app.include_router(router)
return app


def create_app():
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s %(process)-7s %(module)-20s %(message)s',
)

app = FastAPI()
app.include_router(router)
return DishkaApp(
providers=[AdaptersProvider(), InteractorProvider()],
app=app,
app=create_fastapi_app(),
)


Expand Down
3 changes: 3 additions & 0 deletions examples/real_world/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fastapi==0.109.0
aiogram==3.3.0
uvicorn==0.27.0
8 changes: 8 additions & 0 deletions examples/real_world/requirements_test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
-r requirements.txt

pytest==7.*
pytest-asyncio==0.23.*
pytest-repeat==0.9.*

httpx==0.26.*
asgi_lifespan==2.1.*
5 changes: 5 additions & 0 deletions examples/real_world/tests/test_add_products.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
"""
In this test file we use DIshka to provide mocked adapters
though it is not necessary as our interactor is not bound to library
"""

from unittest.mock import Mock

import pytest
Expand Down
49 changes: 49 additions & 0 deletions examples/real_world/tests/test_web.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
"""
In this test example we mock our interactors to check if web view
works correctly. Other option was to only adapters or just use real providers.
We use `fastapi.testclient.TestClient` to send requests to the app
Additionally we need `asgi_lifespan.LifespanManager` to correctly enter
app scope as it is done in real application
"""
from unittest.mock import Mock

import pytest
import pytest_asyncio
from asgi_lifespan import LifespanManager
from fastapi.testclient import TestClient

from dishka import Provider, Scope, provide
from dishka.integrations.fastapi import (
DishkaApp,
)
from main_web import create_fastapi_app
from myapp.use_cases import AddProductsInteractor


class FakeInteractorProvider(Provider):
@provide(scope=Scope.REQUEST)
def add_products(self) -> AddProductsInteractor:
return Mock()


@pytest.fixture
def interactor_provider():
return FakeInteractorProvider()


@pytest_asyncio.fixture
async def client(interactor_provider):
app = DishkaApp(
providers=[interactor_provider],
app=create_fastapi_app(),
)
async with LifespanManager(app):
yield TestClient(app)


@pytest.mark.asyncio
async def test_index(client):
res = client.get("/")
assert res.status_code == 200
assert res.json() == "Ok"
8 changes: 6 additions & 2 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[tox]
requires =
tox>=4
env_list = unit,fastapi-{0092,0109},aiogram-330
env_list = unit,fastapi-{0092,0109},aiogram-330,real_world_example

[testenv]
deps =
Expand All @@ -19,4 +19,8 @@ deps = -r requirements/test.txt
commands = pytest -v tests/unit

[testenv:latest]
install_commands = python -m pip install -U {opts} {packages}
install_commands = python -m pip install -U {opts} {packages}

[testenv:real_world_example]
deps = -r examples/real_world/requirements_test.txt
commands = pytest -v examples/real_world/tests/

0 comments on commit 385756b

Please sign in to comment.