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

FastAPI结合FactoryBoy测试时JWT Token注入问题求助

问题:FastAPI集成JWT后,FactoryBoy测试注入Token遇错

我已经实现FastAPI与JWT的集成,但使用FactoryBoy进行测试时遇到两个问题:

  • 设置oauth2_scheme依赖覆盖时,抛出TypeError错误,提示hash必须为unicode或bytes,而非unittest.mock.MagicMock
  • 移除该依赖覆盖后,请求返回401认证错误,不知道怎么正确在请求头中注入JWT Token

测试代码如下:

def fake_oauth2_token():
    client_token = TestClient(app)
    response = client_token.post(
        "api/auth/login/",
        data={
            "grant_type": "password",
            "username": "me",
            "password": "mypass",
            "scope": "",
            "client_id": "",
            "client_secret": "",
        },
    )
    token = json.loads(response.content)
    return token["access_token"] if token else {}

def test_get_flower():
    """ """
    flower = FlowerFactory()
    mock_session = MagicMock()
    mock_session.query.return_value.all.return_value = [flower]
    app.dependency_overrides[oauth2_scheme] = lambda: fake_oauth2_token()
    app.dependency_overrides[get_db] = lambda: mock_session
    client = TestClient(app)

    response = client.get("api/flower/")
    assert response.status_code == 200

错误信息:

TypeError: hash必须为unicode或bytes,而非unittest.mock.MagicMock


解决方法

核心问题分析

直接覆盖oauth2_scheme依赖的方式有误,且fake_oauth2_token中新建的TestClient会和当前测试的依赖覆盖(比如Mock的数据库会话)冲突,导致Token生成过程中调用了未预期的依赖,触发类型错误。正确的做法是直接在请求头中注入Token,无需修改oauth2_scheme的依赖。

修正后的测试代码

def test_get_flower():
    # 构建测试数据并Mock数据库会话
    flower = FlowerFactory()
    mock_session = MagicMock()
    mock_session.query.return_value.all.return_value = [flower]
    app.dependency_overrides[get_db] = lambda: mock_session
    
    # 使用同一个TestClient完成登录和业务请求,保证依赖一致
    client = TestClient(app)
    
    # 先调用登录接口获取Token
    login_response = client.post(
        "api/auth/login/",
        data={
            "grant_type": "password",
            "username": "me",
            "password": "mypass",
            "scope": "",
            "client_id": "",
            "client_secret": "",
        },
    )
    token = login_response.json().get("access_token")
    
    # 携带Token发送业务请求,遵循OAuth2的Bearer Token格式
    response = client.get(
        "api/flower/",
        headers={"Authorization": f"Bearer {token}"}
    )
    
    # 断言请求成功
    assert response.status_code == 200
    
    # 清空依赖覆盖,避免影响后续测试用例
    app.dependency_overrides.clear()

关键注意点

  • 不要在Token生成函数中新建TestClient,复用测试函数内的客户端,确保依赖(如Mock的DB)统一
  • 请求头的Authorization字段必须遵循Bearer <token>的标准格式,FastAPI的JWT认证会自动解析该格式
  • 测试结束后调用app.dependency_overrides.clear(),防止当前测试的依赖覆盖污染其他用例

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 11:43:24