W.P*_*ill 9 sqlalchemy test-fixture fastapi
我正在编写一个使用 SQLAlchemy 数据库的FastAPI应用程序。我已经从 FastAPI 文档中复制了示例,为了简洁起见,简化了数据库模式。完整的来源在这篇文章的底部。
这有效。我可以uvicorn sql_app.main:app通过 Swagger 文档运行它并与数据库交互。当它运行时,它会test.db在工作目录中创建一个。
现在我想添加一个单元测试。像这样的东西。
from fastapi import status
from fastapi.testclient import TestClient
from pytest import fixture
from main import app
@fixture
def client() -> TestClient:
return TestClient(app)
def test_fast_sql(client: TestClient):
response = client.get("/users/")
assert response.status_code == status.HTTP_200_OK
assert response.json() == []
Run Code Online (Sandbox Code Playgroud)
使用下面的源代码,这将test.db工作目录中的 用作数据库。相反,我想为在测试结束时删除的每个单元测试创建一个新数据库。
我可以将全局database.engine和database.SessionLocal在运行时创建的对象内,像这样:
class UserDatabase:
def __init__(self, directory: Path):
directory.mkdir(exist_ok=True, parents=True)
sqlalchemy_database_url = f"sqlite:///{directory}/store.db"
self.engine = create_engine(
sqlalchemy_database_url, connect_args={"check_same_thread": False}
)
self.SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=self.engine)
models.Base.metadata.create_all(bind=self.engine)
Run Code Online (Sandbox Code Playgroud)
但我不知道如何使用main.get_db,因为Depends(get_db)逻辑最终假设database.engine并且database.SessionLocal在全球范围内可用。
我习惯于使用 Flask,它的单元测试工具会为您处理所有这些。我自己不知道怎么写。有人可以告诉我为了在这个框架中为每个单元测试生成一个新数据库而必须做的最小更改吗?
简化的 FastAPI/SQLAlchemy 应用程序的完整源代码如下。
数据库.py
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
SQLALCHEMY_DATABASE_URL = "sqlite:///./test.db"
engine = create_engine(
SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
Run Code Online (Sandbox Code Playgroud)
模型.py
from sqlalchemy import Column, Integer, String
from database import Base
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
name = Column(String)
age = Column(Integer)
Run Code Online (Sandbox Code Playgroud)
模式.py
from pydantic import BaseModel
class UserBase(BaseModel):
name: str
age: int
class UserCreate(UserBase):
pass
class User(UserBase):
id: int
class Config:
orm_mode = True
Run Code Online (Sandbox Code Playgroud)
粗略的.py
from sqlalchemy.orm import Session
import schemas
import models
def get_user(db: Session, user_id: int):
return db.query(models.User).filter(models.User.id == user_id).first()
def get_users(db: Session, skip: int = 0, limit: int = 100):
return db.query(models.User).offset(skip).limit(limit).all()
def create_user(db: Session, user: schemas.UserCreate):
db_user = models.User(name=user.name, age=user.age)
db.add(db_user)
db.commit()
db.refresh(db_user)
return db_user
Run Code Online (Sandbox Code Playgroud)
主文件
from typing import List
from fastapi import Depends, FastAPI, HTTPException
from sqlalchemy.orm import Session
import schemas
import models
import crud
from database import SessionLocal, engine
models.Base.metadata.create_all(bind=engine)
app = FastAPI()
# Dependency
def get_db():
try:
db = SessionLocal()
yield db
finally:
db.close()
@app.post("/users/", response_model=schemas.User)
def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):
return crud.create_user(db=db, user=user)
@app.get("/users/", response_model=List[schemas.User])
def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
users = crud.get_users(db, skip=skip, limit=limit)
return users
@app.get("/users/{user_id}", response_model=schemas.User)
def read_user(user_id: int, db: Session = Depends(get_db)):
db_user = crud.get_user(db, user_id=user_id)
if db_user is None:
raise HTTPException(status_code=404, detail="User not found")
return db_user
Run Code Online (Sandbox Code Playgroud)
您需要get_db在测试中覆盖您的依赖项,请参阅这些文档。
对于您的固定装置是这样的:
@fixture
def db_fixture() -> Session:
raise NotImplementError() # Make this return your temporary session
@fixture
def client(db_fixture) -> TestClient:
def _get_db_override():
return db_fixture
app.dependency_overrides[get_db] = _get_db_override
return TestClient(app)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4401 次 |
| 最近记录: |