Python结合parameterized与unittest使用patch时参数顺序异常问题
问题原因
这个现象是Python装饰器的执行顺序和parameterized、unittest.patch的注入逻辑共同导致的:
- Python装饰器的应用顺序是「从靠近函数的位置往远离函数的位置依次执行」,你当前的写法中装饰器的执行顺序为:
@patch("package.module.f1")→@patch("package.module.f2")→@parameterized.expand unittest.patch装饰器的逻辑是每次装饰都会把生成的mock对象,追加到被装饰函数的参数列表末尾parameterized.expand装饰器的逻辑是把你传入的参数化用例的参数,按顺序传给被装饰函数的前N个非固定参数
按你当前的装饰器排列顺序,参数的拼接过程如下:
- 初始无装饰的测试函数参数:
self, a, b - 先执行
@patch("package.module.f1"),追加f1到参数末尾 → 参数变为self, a, b, f1 - 再执行
@patch("package.module.f2"),追加f2到参数末尾 → 参数变为self, a, b, f1, f2 - 最后执行
@parameterized.expand,把用例中的[a1,b1]、[a2,b2]按顺序传给参数列表里的a、b位置,所以最终运行时参数顺序就是self, a, b, f1, f2,和你第一个可运行的写法一致。
调整为预期参数顺序的方案
如果想要f1、f2在前,a、b在后的参数顺序,只需要把parameterized.expand装饰器放到所有@patch装饰器的下方(靠近函数的一侧)即可:
@patch("package.module.f2") @patch("package.module.f1") @parameterized.expand([ [a1, b1], [a2, b2] ]) def test_my_func(self, f1, f2, a, b): f1.return_value = "Hello" f2.return_value = "World"
这种写法下装饰器的执行顺序变为:@parameterized.expand → @patch("package.module.f1") → @patch("package.module.f2"),parameterized的参数a、b会被后面执行的patch装饰器追加到mock参数的后面,完全符合你的预期。
内容的提问来源于stack exchange,提问作者Ajx
相关产品推荐
相关产品推荐

