如何基于参数条件部分模拟函数,其余场景使用实际实现?
如何基于参数条件部分模拟函数,其余场景使用实际实现?
我太懂这种需求了——测试时只想针对特定参数的场景mock函数行为,其他情况还是用原函数的真实逻辑,这样既能覆盖特殊case,又能保证测试的真实性。下面给你两种实用的实现方式,都是基于Python的unittest.mock库来做的:
方法一:自定义mock函数,调用原函数处理非目标场景
这种方式最直观:先保留原函数的引用,然后在自定义的mock函数里判断参数,如果是你要mock的pod_number == 5就返回自定义值,否则直接调用原函数执行真实逻辑。
完整的测试代码示例:
from unittest import TestCase, mock # 导入原函数,注意要用未被patch的路径,避免被mock覆盖 from application.triggers import retrieve_pod_size as original_retrieve_pod_size class TestPod(TestCase): def test_pod(self): def conditional_mock(pod_number): # 针对目标参数返回mock值 if pod_number == 5: return 'an object with size 6' # 其他参数直接调用原函数 return original_retrieve_pod_size(pod_number) # 用自定义函数patch目标函数 with mock.patch('application.triggers.retrieve_pod_size', side_effect=conditional_mock): # 测试非mock场景,应该走原逻辑 self.assertEqual(retrieve_pod_size(3), 'an object with size 3') self.assertEqual(retrieve_pod_size(10), 'default object') # 测试mock场景,返回自定义值 self.assertEqual(retrieve_pod_size(5), 'an object with size 6')
方法二:利用side_effect的动态返回特性
其实mock.patch的side_effect参数本身就支持接收一个函数,这个函数会接收原函数的所有参数,你可以在里面做条件判断,本质和方法一类似,但写法更贴合mock库的惯用方式:
from unittest import TestCase, mock from application.triggers import retrieve_pod_size class TestPod(TestCase): def test_pod(self): def mock_side_effect(pod_number): if pod_number == 5: return 'an object with size 6' # 这里直接调用原函数,因为此时原函数还没被patch(在with块内才生效) return retrieve_pod_size(pod_number) with mock.patch('application.triggers.retrieve_pod_size', side_effect=mock_side_effect): self.assertEqual(retrieve_pod_size(3), 'an object with size 3') self.assertEqual(retrieve_pod_size(5), 'an object with size 6') self.assertEqual(retrieve_pod_size(7), 'default object')
注意事项
- 一定要确保patch的路径是被测试代码实际导入函数的路径,比如如果你的业务代码里是
from application.triggers import retrieve_pod_size,那patch就要用'application.triggers.retrieve_pod_size',路径错了mock会不生效。 - 方法一里导入原函数时要起别名,避免和被patch后的函数重名,导致调用的是mock后的函数而非原函数。
备注:内容来源于stack exchange,提问作者syv
相关产品推荐
相关产品推荐

