You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用多个@mock.patch模拟函数内部依赖并解决MagicMock类型错误

问题解答

1. 是否支持多个@mock.patch装饰器?

完全支持,unittest.mock 模块允许叠加使用任意数量的@mock.patch装饰器,用来同时模拟多个不同的依赖对象。

2. 触发类型错误的原因

错误的核心原因是**@mock.patch装饰器的注入参数顺序和你测试函数定义的参数顺序不匹配**:

@mock.patch装饰器的参数注入逻辑是从下往上注入:写在最下方的装饰器对应的mock对象会作为第一个参数传入测试函数,越靠上的装饰器,对应的参数位置越靠后。

你现有代码的装饰器顺序是:

@mock.patch('...check_output')  # 最上层,对应测试函数的第三个参数
@mock.patch('...get_value_a')   # 中间层,对应测试函数的第二个参数
@mock.patch('...get_value_b')   # 最下层,对应测试函数的第一个参数

而你的测试函数参数顺序写的是mock_check_output,val_a, val_b,等于你错误地把get_value_b的mock对象赋值给了mock_check_output、把get_value_a的mock对象赋值给了val_a、把check_output的mock对象赋值给了val_b。你直接把val_a(此时是MagicMock类型的对象)和int类型的0做比较,自然触发类型错误。

额外说明:从你贴出的业务代码看,print_contents_of_cwd是接收val_a、val_b作为入参,本身没有内部调用get_value_a、get_value_b,这种场景下你不需要mock这两个函数,直接传测试用的数值即可。如果你的真实业务逻辑是print_contents_of_cwd内部主动调用这两个函数获取值,那你需要调整业务代码,测试时也不需要主动传参。

解决方案

方案1:调整参数顺序适配注入规则(按你现有写法适配)

from Mack_Test_Practise import list_dir
from unittest import mock, TestCase

class TestExamples(TestCase):
    @mock.patch('Mack_Test_Practise.list_dir.check_output', return_value=b'list_dir.py')
    @mock.patch('Mack_Test_Practise.list_dir.get_value_a', return_value=5)
    @mock.patch('Mack_Test_Practise.list_dir.get_value_b', return_value=3)
    # 参数顺序和装饰器从下到上的注入顺序保持一致
    def test_print_contents_of_file(self, mock_get_value_b, mock_get_value_a, mock_check_output):
        # 从mock对象中获取你预设的返回值,再传入目标函数
        actual_result = list_dir.print_contents_of_cwd(mock_get_value_a.return_value, mock_get_value_b.return_value)
        expected_result = b'list_dir.py'
        self.assertIn(expected_result, actual_result)

方案2:简化不必要的mock(适配你贴出的业务代码逻辑)

因为你当前的print_contents_of_cwd不需要调用get_value_a、get_value_b,直接传参即可:

from Mack_Test_Practise import list_dir
from unittest import mock, TestCase

class TestExamples(TestCase):
    @mock.patch('Mack_Test_Practise.list_dir.check_output', return_value=b'list_dir.py')
    def test_print_contents_of_file(self, mock_check_output):
        # 直接传入测试用的数值,不需要mock另外两个函数
        actual_result = list_dir.print_contents_of_cwd(5, 3)
        expected_result = b'list_dir.py'
        self.assertIn(expected_result, actual_result)

内容的提问来源于stack exchange,提问作者user932061

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 22:06:02