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

Python unittest使用mock.patch时如何动态调整db.find_one的返回值

问题根源

你之前的写法不生效的核心原因是:每次调用mocked_collection()(也就是模拟的get_share_code_collection()被调用)时,unittest.mock都会默认生成一个全新的MagicMock实例。你给临时生成的实例设置find_one.return_value,业务代码实际调用时拿到的是另一个新实例,之前的配置自然不会生效。

解决方案

方案1:固定返回同一个集合Mock实例(最常用)

提前创建一个Mock集合对象,让get_share_code_collection每次调用都返回同一个实例,后续直接修改这个实例的配置即可:

from unittest import mock
@mock.patch("api.utils.get_share_code_collection")
def test_share_code_correct_no_share_types(
    self, mocked_collection, mocked_share_code, user_model
):
    # 先创建固定的集合mock实例
    mock_collection_inst = mock.MagicMock()
    mocked_collection.return_value = mock_collection_inst
    
    # 直接修改这个实例的find_one返回值即可
    mock_collection_inst.find_one.return_value = True
    # 后续业务代码调用get_share_code_collection拿到的都是这个mock_collection_inst,配置生效
    ...

@mock.patch("api.utils.get_share_code_collection")
def test_share_code_no_start_time(
    self, mocked_collection, user_model
):
    mock_collection_inst = mock.MagicMock()
    mocked_collection.return_value = mock_collection_inst
    # 单独设置当前测试用例需要的返回值
    mock_collection_inst.find_one.return_value = False
    ...

方案2:动态追加side_effect返回值

如果同一个测试用例里需要多次调用find_one返回不同值,也可以动态修改side_effect列表,只要你持有同一个find_one的mock对象即可:

@mock.patch("api.utils.get_share_code_collection")
def test_multiple_find_one_calls(self, mocked_collection):
    mock_collection_inst = mock.MagicMock()
    mocked_collection.return_value = mock_collection_inst
    # 初始化side_effect
    mock_collection_inst.find_one.side_effect = [True, False]
    # 后续可以直接追加新的返回值
    mock_collection_inst.find_one.side_effect.append(None)
    mock_collection_inst.find_one.side_effect.extend([{"_id": 1}, {"_id": 2}])
    ...

方案3:按查询条件返回对应值

如果需要根据find_one传入的查询参数动态返回不同结果,可以给side_effect传入自定义函数:

@mock.patch("api.utils.get_share_code_collection")
def test_find_one_by_query(self, mocked_collection):
    mock_collection_inst = mock.MagicMock()
    mocked_collection.return_value = mock_collection_inst
    
    def custom_find_one(query):
        # 根据传入的查询条件返回对应值
        if query.get("specialist_id") == {"$exists": True}:
            return {"specialist_id": 123, "code": "abc123"}
        elif query.get("code") == "test":
            return {"code": "test", "expired": True}
        return None
    
    mock_collection_inst.find_one.side_effect = custom_find_one
    ...

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 12:24:07