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

如何Mock带参数的commutils.UserNameMapper类?解决self参数报错

问题:Mock类实例方法时出现“self param expected”错误

场景代码

待测试的refactorReport方法:

def refactorReport(df):
    """Enhance with additional information as needed"""
    for userclass in ['ClassA', 'ClassB', 'ClassC']:
        df['%s_Region'%userclass] = df[userclass].apply(lambda x: commutils.UserNameMapper(x).Region())
    return df

测试用的DummyUserNameMapper类及测试代码:

class DummyUserNameMapper():
    def __init__(self, thename):
        self.thename = thename
    def Region(self):
        print(self.thename)
        return 'Region%s'%self.thename[-1]

class ModuleTests(unittest.TestCase):
    def setUp(self):
        data = [
            ('Name 1', 'Apple', 'Mango', 'Orange'),
            ('Name 2', 'Pear', 'Apple', 'Banana'),
            ('Name 3', 'Banana', 'Mango', 'Orange'),
            ('Name 4', 'Apple', 'Pear', 'Orange'),
            ('Name 5', 'Pear', 'Mango', 'Orange'),
        ]
        self.records = pd.DataFrame(data, columns=['Name', 'ClassA', 'ClassB', 'ClassC'])

    def test_refactorReport(self):
        with mock.patch("commutils.UserNameMapper", return_value=DummyUserNameMapper):
            print(refactorReport(self.records))

    @mock.patch('commutils.UserNameMapper')
    def test_refactorReport_New(self, mockUser):
        mockUser.return_value = DummyUserNameMapper
        print(refactorReport(self.records))

运行测试时出现“self param expected”错误。

错误原因

你错误地将DummyUserNameMapper类本身赋值给了Mock的return_value。当代码调用commutils.UserNameMapper(x)时,返回的不是类的实例,而是类本身。后续调用.Region()时,Python会把类作为第一个参数传入,但Region方法期望接收的是类的实例(即self参数),因此触发错误。

正确解决方案

方案1:使用side_effect替代return_value

side_effect可以接收一个类,每次调用Mock类时,会自动传入参数创建实例:

class ModuleTests(unittest.TestCase):
    def setUp(self):
        data = [
            ('Name 1', 'Apple', 'Mango', 'Orange'),
            ('Name 2', 'Pear', 'Apple', 'Banana'),
            ('Name 3', 'Banana', 'Mango', 'Orange'),
            ('Name 4', 'Apple', 'Pear', 'Orange'),
            ('Name 5', 'Pear', 'Mango', 'Orange'),
        ]
        self.records = pd.DataFrame(data, columns=['Name', 'ClassA', 'ClassB', 'ClassC'])

    def test_refactorReport(self):
        with mock.patch("commutils.UserNameMapper", side_effect=DummyUserNameMapper):
            result_df = refactorReport(self.records)
            print(result_df)
            # 可添加断言验证结果,例如:
            # self.assertEqual(result_df['ClassA_Region'].iloc[0], 'Regione')

    @mock.patch('commutils.UserNameMapper')
    def test_refactorReport_New(self, mockUser):
        mockUser.side_effect = DummyUserNameMapper
        result_df = refactorReport(self.records)
        print(result_df)

方案2:直接Mock实例的Region方法(更简洁)

无需编写完整的Dummy类,直接MockUserNameMapper实例的Region方法返回值:

class ModuleTests(unittest.TestCase):
    def setUp(self):
        data = [
            ('Name 1', 'Apple', 'Mango', 'Orange'),
            ('Name 2', 'Pear', 'Apple', 'Banana'),
            ('Name 3', 'Banana', 'Mango', 'Orange'),
            ('Name 4', 'Apple', 'Pear', 'Orange'),
            ('Name 5', 'Pear', 'Mango', 'Orange'),
        ]
        self.records = pd.DataFrame(data, columns=['Name', 'ClassA', 'ClassB', 'ClassC'])

    @mock.patch('commutils.UserNameMapper')
    def test_refactorReport_simple(self, mockUser):
        # 获取Mock类的实例对象
        mock_instance = mockUser.return_value
        # 静态返回固定值
        # mock_instance.Region.return_value = 'RegionX'
        
        # 或者根据输入动态返回结果
        def dynamic_region():
            # 获取创建实例时传入的参数x
            x = mockUser.call_args[0][0]
            return 'Region%s' % x[-1]
        mock_instance.Region.side_effect = dynamic_region
        
        result_df = refactorReport(self.records)
        print(result_df)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 05:11:21