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

如何动态构建与Primary类方法同步的Python Dummy类?

解决方案:动态生成Dummy类与测试最佳实践

一、实现自动同步的Dummy类

你原来的代码问题在于在实例初始化时给对象添加属性,而非给类添加方法,导致调用时无法找到对应方法。可以通过以下两种方式实现自动同步Primary的方法:

方式1:类定义时动态添加方法

直接遍历Primary的公共方法,在Dummy类创建时批量添加空实现:

class Primary:
    def foo(self, a, b):
        return a + b
    def bar(self, a, b):
        return a - b

# 定义通用的空实现函数
def dummy_impl(self, *args, **kwargs):
    pass

class Dummy:
    pass

# 遍历Primary的所有非魔法方法,添加到Dummy类
for method_name in dir(Primary):
    if not method_name.startswith("__") and callable(getattr(Primary, method_name)):
        setattr(Dummy, method_name, dummy_impl)

# 测试
d = Dummy()
print(d.foo(1,2))  # 输出 None
print(d.bar(3,1))  # 输出 None

当Primary新增方法时,重新运行这段代码,Dummy会自动同步新方法。

方式2:用元类实现继承自动覆盖

如果希望Dummy继承Primary(保持类型兼容性),可以用元类自动覆盖所有公共方法:

class DummyMeta(type):
    def __new__(cls, name, bases, attrs):
        # 遍历所有基类(这里指Primary)的方法
        for base in bases:
            for method_name in dir(base):
                if not method_name.startswith("__") and callable(getattr(base, method_name)):
                    # 只有当子类未显式定义该方法时,才用空实现覆盖
                    if method_name not in attrs:
                        attrs[method_name] = lambda self, *args, **kwargs: None
        return super().__new__(cls, name, bases, attrs)

class Dummy(Primary, metaclass=DummyMeta):
    pass

# 测试
d = Dummy()
print(isinstance(d, Primary))  # 输出 True(保持类型兼容)
print(d.foo(1,2))  # 输出 None

这种方式既保持了Dummy与Primary的类型一致性,又自动同步方法。

二、测试场景的最佳实践

手动维护Dummy类(即使是动态生成)其实没必要,Python标准库unittest.mock提供的Mock/MagicMock是更优方案:

使用Mock替代Dummy类

Mock可以模拟任意对象,配合spec参数可以限制只能调用Primary存在的方法,避免测试中出现拼写错误:

from unittest.mock import Mock

# 创建模拟Primary的实例,spec参数确保方法与Primary一致
primary_mock = Mock(spec=Primary)

# 如果需要特定方法返回指定值,可单独设置
primary_mock.foo.return_value = 10

# 将mock传给依赖Primary的对象
class OtherClass:
    def __init__(self, primary):
        self.primary = primary
    def do_something(self):
        return self.primary.foo(1,2)

obj = OtherClass(primary=primary_mock)
print(obj.do_something())  # 输出 10

这种方式的优势:

  • 无需维护Dummy类,Primary更新方法后自动适配
  • 可灵活设置方法的返回值、调用次数等,满足不同测试场景
  • 内置断言方法(如assert_called_once_with)可验证方法调用情况

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 20:15:24