如何动态构建与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
相关产品推荐
相关产品推荐

