如何使用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
相关产品推荐
相关产品推荐

