Python3中调用函数并仅Mock返回码/返回值的实现方法
在Python 3中Mock函数返回值同时保留原有执行逻辑
我懂你要的效果——让函数完整跑一遍原本的所有代码逻辑,但最后返回你指定的模拟值对吧?这在测试场景里太常用了,比如你想验证函数内部的业务逻辑是否正常,但不想依赖它原本的返回结果(比如涉及外部API调用、数据库查询的情况)。
下面直接给你两种实用的实现方式:
方法一:用自定义包装函数配合side_effect
先看代码示例,假设我们有一个原函数:
from unittest.mock import patch # 这是你要包装的原函数 def calculate_total(price, quantity): print(f"原函数执行:计算价格{price} * 数量{quantity}") # 原逻辑里可能还有其他操作,比如日志、调用其他服务等 return price * quantity
现在我们想让它执行全部原逻辑,但固定返回999:
def wrap_with_original_logic(target_func): def wrapper(*args, **kwargs): # 第一步:完整执行原函数的所有逻辑 target_func(*args, **kwargs) # 第二步:返回我们指定的模拟值 return 999 return wrapper # 使用patch来替换原函数 with patch('__main__.calculate_total', side_effect=wrap_with_original_logic(calculate_total)): result = calculate_total(10, 5) print(f"模拟后的返回值:{result}")
运行这段代码,你会看到原函数的打印语句正常输出,最后返回的却是我们指定的999,完美符合需求。
方法二:更简洁的内联写法
如果不想单独定义包装函数,也可以直接在patch里写内联的side_effect:
with patch('__main__.calculate_total') as mock_calc: def custom_effect(*args, **kwargs): # 先跑原函数逻辑 calculate_total(*args, **kwargs) # 返回模拟值 return 1000 mock_calc.side_effect = custom_effect res = calculate_total(20, 3) print(f"返回结果:{res}")
关键知识点提醒
- 别用
return_value!很多新手一开始会直接给mock对象赋值mock_calc.return_value = 999,但这样原函数根本不会执行,只会直接返回指定值,完全不符合你的需求。 - 注意patch的路径:如果你的原函数在其他模块(比如
my_utils.py)里,要patchmy_utils.calculate_total而不是直接写函数名,确保路径正确才能成功替换。
内容的提问来源于stack exchange,提问作者HippoMan
相关产品推荐
相关产品推荐

