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

如何在FastAPI的Pytest测试中正确实现Mock认证?

解决FastAPI+pytest中Mock认证依赖的问题

你在测试FastAPI端点时尝试Mock认证依赖,运行测试时触发错误:

AttributeError: 'FastAPI' object has no attribute 'authenticate'

核心原因是你错误地通过app.authenticate引用认证函数,但authenticate是main.py中的独立异步函数,并非FastAPI实例app的属性。


正确的依赖覆盖方案

1. 导入原始认证函数

在测试文件中,从main模块直接导入authenticate函数:

from main import app, authenticate  # 新增导入authenticate

2. 修正依赖覆盖代码

将原来的app.dependency_overrides[app.authenticate] = fake_authenticate替换为:

app.dependency_overrides[authenticate] = fake_authenticate

3. 优化Mock认证函数(可选)

原authenticate函数仅做验证逻辑(通过则继续,不通过抛异常),无返回值,所以Mock函数只需保持签名一致即可:

async def fake_authenticate(
        apitoken: Optional[str] = None,
        account: Optional[str] = None,
        sessionHost: Optional[str] = None
):
    # 模拟认证通过,无需额外逻辑
    pass

完整修正后的测试代码

import os
from typing import Optional
from fastapi.testclient import TestClient
from unittest.mock import patch, AsyncMock
from main import app, authenticate  # 导入authenticate
from tests.mock_data import test_roles_data

os.environ["TEST_ENV"] = "test"
client = TestClient(app)

async def fake_authenticate(
        apitoken: Optional[str] = None,
        account: Optional[str] = None,
        sessionHost: Optional[str] = None
):
    pass  # 模拟认证通过

# 正确覆盖认证依赖
app.dependency_overrides[authenticate] = fake_authenticate

@patch('routers.base.parse_params', new_callable=AsyncMock)
@patch('services.roles.Roles.get_json', new_callable=AsyncMock)
def test_roles_endpoint(mock_parse_params, mock_get_json):
    mock_get_json.return_value = test_roles_data
    mock_parse_params.return_value = ("custom_fields_value", "2023-01-01", "2023-01-31")

    response = client.get("/roles", headers={
        'apitoken': 'apitoken',
        'account': 'account',
        'sessionHost': 'sessionHost',
    },
                          params={"start_date": "2023-01-01", "end_date": "2023-01-31"})

    assert response.status_code == 200
    assert response.json() == test_roles_data  # 可启用该断言验证返回值

# 清理环境变量
del os.environ["TEST_ENV"]

额外优化:用pytest fixture管理依赖覆盖

为避免测试间的依赖污染,建议用fixture自动管理依赖的覆盖与恢复:

import pytest

@pytest.fixture(autouse=True)
def override_authenticate():
    # 保存原始依赖
    original_dep = app.dependency_overrides.get(authenticate)
    # 覆盖依赖
    app.dependency_overrides[authenticate] = fake_authenticate
    yield
    # 测试结束后恢复原始依赖
    app.dependency_overrides[authenticate] = original_dep

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 23:35:03