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

Python单元测试中用patch为mock函数设置不同返回值的方法

在Python单元测试中为Mock函数设置不同返回值

要解决每次调用mock函数返回相同结果的问题,核心是利用unittest.mock.Mock的side_effect属性替代return_value,它支持按调用顺序返回不同结果,或根据传入参数动态返回对应数据,以下是两种常用实现方式:

方法一:按调用顺序返回固定列表值

如果测试中user_ids的顺序固定,直接给side_effect传入一个与调用次数匹配的返回值列表,每次调用mock函数时会依次取列表中的元素:

from unittest.mock import patch
from your_module import get_users  # 替换成你的主函数所在模块
import unittest

class TestGetUsers(unittest.TestCase):
    @patch("api.get_users_from_api")
    def test_get_users(self, mock_get_users):
        user_ids = [1, 2, 3]
        # 按调用顺序设置对应返回值,分别匹配user_id 1、2、3
        mock_get_users.side_effect = [
            {"id": 1, "first_name": "John", "last_name": "Doe"},
            {"id": 2, "first_name": "Jane", "last_name": "Smith"},
            {"id": 3, "first_name": "Bob", "last_name": "Brown"}
        ]
        get_users(user_ids)
        
        # 可选:验证mock函数的调用情况
        self.assertEqual(mock_get_users.call_count, 3)
        mock_get_users.assert_any_call(1)
        mock_get_users.assert_any_call(2)
        mock_get_users.assert_any_call(3)

方法二:根据传入参数动态返回值

如果需要根据调用时传入的user_id动态返回对应数据,可定义一个自定义函数,接收mock被调用时的参数,返回匹配的结果:

from unittest.mock import patch
from your_module import get_users
import unittest

def mock_user_response(user_id):
    # 用字典映射user_id到对应的用户数据
    user_data_map = {
        1: {"id": 1, "first_name": "John", "last_name": "Doe"},
        2: {"id": 2, "first_name": "Jane", "last_name": "Smith"},
        3: {"id": 3, "first_name": "Bob", "last_name": "Brown"}
    }
    # 对于未定义的user_id,返回默认值
    return user_data_map.get(user_id, {"id": user_id, "first_name": "Unknown", "last_name": "User"})

class TestGetUsers(unittest.TestCase):
    @patch("api.get_users_from_api")
    def test_get_users(self, mock_get_users):
        user_ids = [1, 3, 2, 4]
        # 将自定义函数赋值给side_effect
        mock_get_users.side_effect = mock_user_response
        get_users(user_ids)
        
        # 可选:验证特定调用的返回值
        self.assertEqual(mock_get_users(4), {"id": 4, "first_name": "Unknown", "last_name": "User"})

补充说明

  • 如果side_effect传入的列表长度小于调用次数,超出次数的调用会抛出StopIteration异常;
  • 自定义函数的参数会与mock函数被调用时的参数完全一致,因此可以根据任意传入参数动态生成返回值;
  • 若需要测试错误分支,也可以将异常类或实例传入side_effect,触发异常场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 01:07:25