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
相关产品推荐
相关产品推荐

