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

如何使用unittest和Mock模拟返回可调用函数的Python函数?

用unittest.mock模拟返回函数的函数

要模拟像func_B这种返回另一个函数的函数,核心是让外层模拟对象的return_value指向一个可调用的模拟对象(Mock本身默认就是可调用的)。下面结合你的代码给出具体测试方案:

测试示例代码

假设你的业务代码在mymodule.py中,测试文件如下:

import unittest
from unittest.mock import Mock, patch
from mymodule import Object, func_A, func_B

class TestNestedFuncCalls(unittest.TestCase):
    def test_call_flow_validation(self):
        # 模拟func_B返回的函数(即原func_A)
        mock_inner_func = Mock(return_value="mocked_result")
        # 替换func_B,让它返回我们定义的模拟函数
        with patch("mymodule.func_B", return_value=mock_inner_func) as mock_outer_func:
            obj = Object()
            z = func_B(func_A)(obj)

            # 验证func_B是否被正确调用,参数是原func_A
            mock_outer_func.assert_called_once_with(func_A)
            # 验证返回的模拟函数是否被传入obj调用
            mock_inner_func.assert_called_once_with(obj)
            # 验证最终结果符合模拟返回值
            self.assertEqual(z, "mocked_result")

    def test_mocked_func_a_behavior(self):
        # 直接模拟原func_A的行为,跳过真实的mul2逻辑
        with patch("mymodule.func_A") as mock_func_a:
            # 让模拟的func_A返回一个自定义的Object实例
            test_obj = Object()
            test_obj.number = 200
            mock_func_a.return_value = test_obj

            obj = Object()
            z = func_B(func_A)(obj)

            # 验证func_A被传入obj调用
            mock_func_a.assert_called_once_with(obj)
            # 验证最终返回的是我们预设的对象
            self.assertEqual(z.number, 200)

    def test_custom_returned_func(self):
        # 让func_B返回一个完全自定义的可调用逻辑
        def custom_func(x):
            return f"processed_{x.__class__.__name__}"
        
        with patch("mymodule.func_B", return_value=custom_func):
            obj = Object()
            z = func_B(func_A)(obj)

            # 验证最终结果符合自定义函数的返回值
            self.assertEqual(z, "processed_Object")

if __name__ == "__main__":
    unittest.main()

关键技巧说明

  • 模拟返回可调用对象:Mock实例默认支持被调用,因此只需将外层模拟函数(如mock_outer_func)的return_value设置为另一个Mock,就能模拟“返回函数”的行为。
  • 隔离真实函数:使用patch上下文管理器或装饰器替换模块中的真实函数,避免测试影响真实逻辑。
  • 验证调用细节:通过assert_called_once_with、call_count等方法,验证函数的调用参数、次数是否符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 04:54:24