Python中如何在断言函数被调用后忽略后续函数执行?
解决TDD中跳过未开发代码的测试问题
针对你在TDD实践中遇到的「需要断言函数被调用,同时跳过后续未开发代码」的需求,这里提供两种实用方案:
方案一:通过异常终止后续代码执行
这种方法让被mock的目标函数在调用时抛出自定义异常,从而终止原函数的后续逻辑执行,同时在测试中捕获该异常避免失败。
修改后的测试代码:
from unittest.mock import Mock, patch # 定义用于终止执行的自定义异常 class StopFuncExecution(Exception): pass def test_a_is_called_during_func(): mocked_a = Mock(side_effect=StopFuncExecution) with patch("your_module.A.a", new=mocked_a): # 替换为实际的模块路径 try: A().func() except StopFuncExecution: # 捕获异常,跳过后续代码执行 pass # 断言a方法被调用一次 mocked_a.assert_called_once()
关键逻辑
- 自定义异常
StopFuncExecution仅用于标记执行终止点,无其他业务含义。 - 给
mocked_a设置side_effect后,self.a()被调用时会触发异常,直接跳出func的执行流程,后续的self.b()(或其他未开发代码)完全不会被执行。 - 测试只关注
a是否被调用,完全不受后续未实现逻辑的影响,后续完善func时无需修改该测试。
方案二:直接模拟核心行为(适合TDD早期)
如果func的整体逻辑还未明确,也可以直接模拟func的核心调用逻辑,绕过原函数的未实现部分:
from unittest.mock import Mock def test_a_is_called_during_func(): # 创建A类的mock实例,保留类的结构(spec参数) mock_instance = Mock(spec=A) # 手动模拟func的核心行为:调用self.a() mock_instance.func = lambda: mock_instance.a() # 执行模拟的func mock_instance.func() # 断言a方法被调用 mock_instance.a.assert_called_once()
适用场景
这种方案完全脱离原func的未实现代码,在TDD最早期(甚至还没写func的完整逻辑)就能验证「func应该调用a」这个核心需求,后续完善func的实现后,只要核心行为不变,测试无需调整。
方案对比
| 方案 | 优点 | 适用场景 |
|---|---|---|
| 异常终止 | 保留原func的部分执行逻辑,更贴近真实运行场景 | 已经写了func的部分逻辑,需要跳过后续未实现代码 |
| 模拟核心行为 | 完全不受原函数未实现代码影响,测试更独立 | TDD早期,func逻辑尚未明确,仅需验证核心调用关系 |
内容的提问来源于stack exchange,提问作者Mounir
相关产品推荐
相关产品推荐

