Skip to content

Commit 2a791ee

Browse files
committed
refactored factory-boy support and made some doc corrections
1 parent 7dacc9e commit 2a791ee

File tree

6 files changed

+35
-66
lines changed

6 files changed

+35
-66
lines changed

docs/testing/index.md

Lines changed: 21 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -216,47 +216,52 @@ Now, let's create a factory for our user model in `tests/factories.py`:
216216

217217
```python title="tests/factories.py"
218218
import factory
219-
from ellar_sql.factory import EllarSQLFactory, SESSION_PERSISTENCE_FLUSH
220219
from db_learning.models import User
221-
from . import common
220+
from ellar.app import current_injector
221+
from sqlalchemy.orm import Session
222+
223+
from ellar_sql.factory import SESSION_PERSISTENCE_FLUSH, EllarSQLFactory
224+
225+
226+
def _get_session():
227+
session = current_injector.get(Session)
228+
return session
222229

223230
class UserFactory(EllarSQLFactory):
224231
class Meta:
225232
model = User
226233
sqlalchemy_session_persistence = SESSION_PERSISTENCE_FLUSH
227-
sqlalchemy_session_factory = lambda: common.Session()
234+
sqlalchemy_session_factory = _get_session
228235

229236
username = factory.Faker('username')
230237
email = factory.Faker('email')
231238
```
232239

233-
The `UserFactory` depends on a database session. Since the pytest fixture we created applies to it,
234-
we also need a session factory in `tests/common.py`:
235-
236-
```python title="tests/common.py"
237-
from sqlalchemy import orm
238-
239-
Session = orm.scoped_session(orm.sessionmaker())
240-
```
240+
The `UserFactory` depends on a database Session as you see from `_get_session()` function.
241+
We need to ensure that test fixture provides `ApplicationContext` for `current_injector` to work.
241242

242-
Additionally, we require a fixture responsible for configuring the Factory session in `tests/conftest.py`:
243+
So in `tests/conftest.py`, we make `tm` test fixture to run application context:
243244

244245
```python title="tests/conftest.py"
245246
import os
247+
246248
import pytest
247-
import sqlalchemy as sa
249+
from db_learning.root_module import ApplicationModule
248250
from ellar.common.constants import ELLAR_CONFIG_MODULE
249251
from ellar.testing import Test
252+
from ellar.threading.sync_worker import execute_async_context_manager
253+
250254
from ellar_sql import EllarSQLService
251-
from db_learning.root_module import ApplicationModule
252-
from . import common
253255

254256
os.environ.setdefault(ELLAR_CONFIG_MODULE, "db_learning.config:TestConfig")
255257

256258
@pytest.fixture(scope='session')
257259
def tm():
258260
test_module = Test.create_test_module(modules=[ApplicationModule])
259-
yield test_module
261+
app = test_module.create_application()
262+
263+
with execute_async_context_manager(app.application_context()):
264+
yield test_module
260265

261266
# Fixture for creating a database session for testing
262267
@pytest.fixture(scope='session')
@@ -270,29 +275,8 @@ def db(tm):
270275

271276
# Dropping all tables after the tests
272277
db_service.drop_all()
273-
274-
# Fixture for creating a database session for testing
275-
@pytest.fixture(scope='session')
276-
def db_session(db, tm):
277-
db_service = tm.get(EllarSQLService)
278-
279-
yield db_service.session_factory()
280-
281-
# Removing the session factory
282-
db_service.session_factory.remove()
283-
284-
@pytest.fixture
285-
def factory_session(db, tm):
286-
engine = tm.get(sa.Engine)
287-
common.Session.configure(bind=engine)
288-
yield
289-
common.Session.remove()
290278
```
291279

292-
In the `factory_session` fixture, we retrieve the `Engine` registered in the DI container by **EllarSQLModule**.
293-
Using this engine, we configure the common `Session`. It's important to note that if you are using an
294-
async database driver, **EllarSQLModule** will register `AsyncEngine`.
295-
296280
With this setup, we can rewrite our `test_username_must_be_unique` test using `UserFactory` and `factory_session`:
297281

298282
```python title="tests/test_user_model.py"
12 KB
Binary file not shown.

samples/db-learning/tests/common.py

Lines changed: 0 additions & 3 deletions
This file was deleted.
Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,23 @@
11
import os
22

33
import pytest
4-
import sqlalchemy as sa
54
from db_learning.root_module import ApplicationModule
65
from ellar.common.constants import ELLAR_CONFIG_MODULE
76
from ellar.testing import Test
7+
from ellar.threading.sync_worker import execute_async_context_manager
88

99
from ellar_sql import EllarSQLService
1010

11-
from . import common
12-
1311
os.environ.setdefault(ELLAR_CONFIG_MODULE, "db_learning.config:TestConfig")
1412

1513

1614
@pytest.fixture(scope="session")
1715
def tm():
1816
test_module = Test.create_test_module(modules=[ApplicationModule])
19-
yield test_module
17+
app = test_module.create_application()
18+
19+
with execute_async_context_manager(app.application_context()):
20+
yield test_module
2021

2122

2223
@pytest.fixture(scope="session")
@@ -26,23 +27,5 @@ def db(tm):
2627

2728
yield
2829

29-
db_service.drop_all()
30-
31-
32-
@pytest.fixture(scope="session")
33-
def db_session(db, tm):
34-
db_service = tm.get(EllarSQLService)
35-
36-
yield db_service.session_factory()
37-
3830
db_service.session_factory.remove()
39-
40-
41-
@pytest.fixture
42-
def factory_session(db, tm):
43-
engine = tm.get(sa.Engine)
44-
common.Session.configure(bind=engine)
45-
46-
yield
47-
48-
common.Session.remove()
31+
db_service.drop_all()
Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
11
import factory
22
from db_learning.models import User
3+
from ellar.app import current_injector
4+
from sqlalchemy.orm import Session
35

46
from ellar_sql.factory import SESSION_PERSISTENCE_FLUSH, EllarSQLFactory
57

6-
from . import common
8+
9+
def _get_session():
10+
session = current_injector.get(Session)
11+
return session
712

813

914
class UserFactory(EllarSQLFactory):
1015
class Meta:
1116
model = User
1217
sqlalchemy_session_persistence = SESSION_PERSISTENCE_FLUSH
13-
sqlalchemy_session_factory = common.Session
18+
sqlalchemy_session_factory = _get_session
1419

1520
username = factory.Faker("user_name")
1621
email = factory.Faker("email")

samples/db-learning/tests/test_user_model.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
# db_session.commit()
2121

2222

23-
def test_username_must_be_unique(factory_session):
23+
def test_username_must_be_unique(db):
2424
user1 = UserFactory()
2525
with pytest.raises(sa_exc.IntegrityError):
2626
UserFactory(username=user1.username)

0 commit comments

Comments
 (0)