0

I'm writing pytest tests for my FastAPI async project. Tests causes error :

session.add(user)

AttributeError: 'async_generator' object has no attribute 'add'

conftest.py:

SQLALCHEMY_DATABASE_URL = f'postgresql+asyncpg://{USER}:{PASSWORD}@{HOST}/{DB}_test'

engine = asyncio.create_async_engine(SQLALCHEMY_DATABASE_URL)
SessionTesting = sessionmaker(
    bind=engine,
    autocommit=False,
    autoflush=False,
    expire_on_commit=False,
    class_=asyncio.AsyncSession
)


@pytest.fixture(name='session')
async def session_fixture() -> Generator[SessionTesting, None, None]:
    Base.metadata.create_all(engine)
    async with SessionTesting(bind=engine.connect()) as session:
    yield session
    Base.metadata.drop_all(engine)

test_auth.py:

@pytest.mark.asyncio
async def test_get_token(session: SessionTesting, create_user):
    # async with AsyncClient(app=app, base_url='http://test') as ac:
    user = User(
    first_name='fixture',
    last_name='fixture',
    username='fixture',
    password=await get_hash('fixture')
    )
    session.add(user)
    await session.commit()
    async with AsyncClient(app=app, base_url='http://localhost:8000') as ac:
    credentials = {
        'username': 'fixture',
        'password': 'fixture'
    }
    response = await ac.post('/token/get_token', data=credentials, headers={"content-type": "application/x-www-form-urlencoded"})
    assert response.status_code == 200

Any ideas?

Daniil Fajnberg
  • 12,753
  • 2
  • 10
  • 41
  • Does this answer your question? [AttributeError in pytest with asyncio after include code in fixtures](https://stackoverflow.com/questions/72996818/attributeerror-in-pytest-with-asyncio-after-include-code-in-fixtures) – Daniil Fajnberg Jun 05 '23 at 14:14
  • I tried this: Set asyncio_mode to auto—see readthedocs and concepts—in which case you can omit pytest.mark.asyncio and use pytest.fixture for fixtures, OR Error is the same – Konstantinos Jun 05 '23 at 14:59
  • I tried to change pytest.fixture to this: @pytest_asyncio.fixture(name="session") tests/conftest.py:52: in session_fixture Base.metadata.create_all(engine) AttributeError: 'AsyncEngine' object has no attribute '_run_ddl_visitor' – Konstantinos Jun 05 '23 at 14:59

1 Answers1

1

You are yielding session (which seems to also be a fixture defined somewhere above) inside session_fixture, but you are not passing it as an argument to session_fixture. That results in yielding async generator instead of session.

@pytest.fixture(name='session')
async def session_fixture():
    ...

should be

@pytest.fixture(name='session')
async def session_fixture(session):
    ...

and also

@pytest.mark.asyncio
async def test_get_token(session: SessionTesting, create_user):

should be

@pytest.mark.asyncio
async def test_get_token(session_fixture: SessionTesting, create_user):
sudden_appearance
  • 1,968
  • 1
  • 4
  • 15