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

测试使用Motor的FastAPI update_one接口时出现'object MagicMock can't be used in 'await' expression'断言错误

测试使用Motor的FastAPI update_one接口时出现'object MagicMock can't be used in 'await' expression'断言错误

嘿,我看了你的代码,这个报错主要是因为mock设置时机不对,而且没有正确模拟MongoDB客户端的层级结构,让我给你捋一捋怎么改:

问题根源

  1. mock设置太晚:你是先发送了请求client.put(...),之后才给mock_motor_client.update_one赋值,这时候请求已经执行完了,代码里的await col.update_one根本没用到你设置的mock,自然会报错。
  2. mock层级不匹配:你的接口代码里是从mongo_client["db"]["col"]拿到集合对象,再调用它的update_one方法,但你直接给mock_motor_client加了update_one,这和实际的调用路径完全对不上,代码执行时找不到能await的mock方法。

修正后的测试代码

@pytest.fixture(scope="session")
async def mock_motor_client():
    mock_client = AsyncMock()
    yield mock_client


@pytest.mark.asyncio
async def test_shield_disable_success(mock_motor_client):
    app = FastAPI()
    app.include_router(router)
    app.dependency_overrides[connection] = lambda: mock_motor_client
    
    # 1. 模拟MongoDB的层级:client -> db -> col
    mock_col = AsyncMock()
    # 设置update_one的返回值,匹配接口需要的matched_count和modified_count
    mock_col.update_one.return_value = AsyncMock(matched_count=1, modified_count=1)
    # 用__getitem__模拟通过["db"]获取数据库的行为,返回我们的mock集合
    mock_motor_client.__getitem__.side_effect = lambda key: {
        "db": mock_col
    }[key]

    client = TestClient(app)
    
    # 2. 先把mock都设置好,再发送请求
    response = client.put("/v2/shield?a=false")

    # 3. 断言结果
    assert response.status_code == 200
    # 额外可以断言update_one是否被正确调用(可选,但能确保接口逻辑正确)
    mock_col.update_one.assert_called_once_with(
        {"foo": "bar"}, {"$set": {"x": False}}
    )

关键调整点

  • 提前设置mock:所有mock的配置都要放在发送请求之前,这样接口代码执行时才能用到正确的mock对象。
  • 模拟层级结构:用__getitem__来模拟通过键名获取数据库和集合的行为,让mongo_client["db"]["col"]能返回我们预先准备好的mock_col,这样调用col.update_one时就是在调用一个正确的AsyncMock方法,不会再出现await的错误。
  • 可选的调用断言:加上mock_col.update_one.assert_called_once_with(...)可以验证接口是否按照预期调用了数据库方法,让测试更严谨。

备注:内容来源于stack exchange,提问作者user30017120

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 19:33:08