You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在pytest中调用FastAPI数据库报错:Depends对象无query属性

问题描述

测试过程中尝试获取创建的测试用户以便在测试结束时删除,遇到错误:

FAILED tests_main.py::test_delete_new_users - AttributeError: 'Depends' object has no attribute 'query'

测试代码如下:

def test_delete_new_users(db: Session = Depends(database.get_db)):
    auth = client.post('/token',
                       data={'username': 'test123', 'password': 'test123'}
                       )
    access_token = auth.json().get('access_token')
    user = db.query(models.User).filter(models.User.username == 'test123').first()

    response = client.post('/user/delete/' + user.user_id,
                           headers={
                               'Authorization': 'bearer' + access_token
                           })
    assert response.status_code == 200

疑问:是否需要编写单独的API(比如get_user_id_with_username)通过用户名获取用户?或者有没有办法在pytest中直接进行数据库调用?因为了解到Depends仅可用于API调用。


解决方案
  • 直接在pytest中获取数据库会话,不要用Depends
    Depends是FastAPI用于接口层依赖注入的工具,不能直接用于pytest测试函数的参数注入。你可以在测试里直接调用database.get_db()生成会话实例:

    def test_delete_new_users():
        db = next(database.get_db())  # 从生成器中取出数据库会话
        auth = client.post('/token',
                           data={'username': 'test123', 'password': 'test123'}
                           )
        access_token = auth.json().get('access_token')
        user = db.query(models.User).filter(models.User.username == 'test123').first()
    
        # 注意Bearer后加空格,用f-string拼接更清晰
        response = client.post(f'/user/delete/{user.user_id}',
                               headers={
                                   'Authorization': f'Bearer {access_token}'
                               })
        assert response.status_code == 200
    

    用完会话后,可手动调用db.close()关闭,或者依赖数据库连接池自动管理。

  • 无需额外编写API
    直接在测试中操作数据库是更高效的方案,避免为测试新增不必要的API接口,减少代码维护成本。

  • 进阶:用pytest fixture管理数据库会话
    可以封装一个fixture来统一管理测试用的数据库会话,还能在测试前后自动清理数据,避免测试数据污染:

    import pytest
    from sqlalchemy.orm import Session
    from database import get_db
    
    @pytest.fixture(scope="function")
    def db_session():
        db = next(get_db())
        try:
            yield db
        finally:
            # 测试结束后回滚事务,清理测试数据
            db.rollback()
            db.close()
    
    def test_delete_new_users(db_session: Session):
        auth = client.post('/token',
                           data={'username': 'test123', 'password': 'test123'}
                           )
        access_token = auth.json().get('access_token')
        user = db_session.query(models.User).filter(models.User.username == 'test123').first()
    
        response = client.post(f'/user/delete/{user.user_id}',
                               headers={
                                   'Authorization': f'Bearer {access_token}'
                               })
        assert response.status_code == 200
    

内容的提问来源于stack exchange,提问作者Vedo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 11:45:38