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

pytest mocker如何为同一流程两次外部调用返回不同mock值

问题原因

你写两个fixture分别patch同一个save_details方法时,后加载的test_201_mock2会完全覆盖前一个fixture的patch配置,相当于最终只有第二个mock生效,不管方法被调用多少次,都会固定返回test_201_mock2里设置的返回值,自然两次拿到的ID重复。
不需要写两个独立的mock fixture,单个mock配置就可以实现按调用顺序返回不同值的需求。

解决方案

使用mock对象的side_effect参数,将需要按调用顺序返回的结果组成列表传入即可:mock被调用时会按顺序依次返回列表中的元素,第一次调用取第一个元素,第二次调用取第二个元素,以此类推。

正确的Mock写法

@pytest.fixture
def mock_save_details(mocker):
    """按调用顺序返回不同的save_details响应"""
    return mocker.patch(
        # 注意:此处路径必须替换为**业务代码中导入save_details的实际路径**,不要填方法定义的源路径
        "your_biz_module.save_details",
        side_effect=[
            # 第一次调用返回值
            (
                "201",
                {
                    "ACK": {
                        "id": "e944126b-db78-4711-9f97-83c2cd1e09a4",
                    }
                },
            ),
            # 第二次调用返回值
            (
                "201",
                {
                    "ACK": {
                        "id": "4758a428-8f33-4dc8-bb64-a500855f9a8c",
                    }
                },
            )
        ]
    )

测试用例调整

测试用例中只需要引入这一个mock fixture即可,不需要同时传入原来的两个mock:

async def test_create_valid_resource_201(
    mock_save_details,
    # 其余原有依赖fixture
    ...
) -> None:
    """
    测试合法POST请求返回201响应的逻辑
    """
    # 执行业务测试逻辑
    # ...

    # 可选:校验mock调用次数符合预期
    assert mock_save_details.call_count == 2
扩展说明
  • 如果需要更多次调用返回不同值,直接按调用顺序往side_effect的列表中追加对应返回值即可。
  • 如果需要模拟某一次调用抛出异常,直接将异常实例放到列表对应位置即可,例如:
    side_effect=[第一次正常返回值, TimeoutError("mock请求超时"), 第三次正常返回值]
    
  • 禁止对同一个目标重复patch:后执行的patch会直接替换前一个patch生成的mock对象,永远不会出现多个mock同时拦截同一个方法调用的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 11:57:11