Files
浅念 b9fcf17ae4 feat: db base + config tests
Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-01 11:04:44 +08:00

59 lines
1.9 KiB
Python

"""Tests for app.db.base — Base class, async engine + sessionmaker plumbing.
These tests build an isolated in-memory SQLite async engine; they never touch
the production MySQL engine defined in app.db.base.
"""
import sqlalchemy as sa
from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine
from sqlalchemy.orm import Mapped, mapped_column
from app.db.base import Base, async_session_maker
def test_base_is_declarative_subclass():
"""Base must be a DeclarativeBase subclass (SQLAlchemy 2.0 style)."""
from sqlalchemy.orm import DeclarativeBase
assert issubclass(Base, DeclarativeBase)
def test_async_session_maker_is_async_sessionmaker():
"""async_session_maker must be an async_sessionmaker instance."""
assert isinstance(async_session_maker, async_sessionmaker)
async def test_round_trip_through_in_memory_sqlite():
"""Build a throwaway model, create tables, insert + query a row.
Uses an in-memory async SQLite engine built locally inside the test so the
production MySQL engine is never exercised here.
"""
class _Row(Base):
__tablename__ = "test_row"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(sa.String(50))
engine = create_async_engine("sqlite+aiosqlite:///:memory:")
try:
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
SessionLocal = async_sessionmaker(engine, expire_on_commit=False)
async with SessionLocal() as session:
session.add(_Row(id=1, name="hello"))
await session.commit()
fetched = (
await session.execute(sa.select(_Row).where(_Row.id == 1))
).scalar_one()
assert fetched.id == 1
assert fetched.name == "hello"
finally:
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.drop_all)
await engine.dispose()