Python中如何替换父类为Mock类,测试含super()调用的子类?
替换子类父类以消除测试中的硬件依赖
场景说明
现有三个Python文件结构如下:
parent.py:包含依赖硬件的父类
class Parent: def write(self): # 真实硬件操作代码 pass
child.py:继承Parent的子类,内部通过super().write()调用父类方法
from parent import Parent class Child(Parent): def write(self): # 子类业务逻辑 super().write()
mock_parent.py:模拟Parent的类,无硬件依赖
from parent import Parent class MockParent(Parent): def write(self): # 模拟实现,替代硬件操作 pass
需求是在测试Child类时,用MockParent替换Parent,消除硬件依赖,但之前尝试mock patch修改导入、基类、super均未成功,希望用简洁的修补方案,而非直接替换Child对象内部实现。
可行解决方案
方案1:修改Child类的基类列表
直接替换Child的__bases__属性,让它继承MockParent而非原Parent,这样super().write()会调用MockParent的实现:
from child import Child from mock_parent import MockParent def test_child_write(): # 保存原基类,测试后恢复避免影响其他用例 original_bases = Child.__bases__ try: Child.__bases__ = (MockParent,) child = Child() child.write() # 添加测试断言,比如验证MockParent的write方法是否被调用 finally: Child.__bases__ = original_bases
方案2:修补child模块的Parent导入
用unittest.mock.patch替换child模块中导入的Parent为MockParent,之后重新加载Child类:
import importlib from unittest.mock import patch import child from mock_parent import MockParent def test_child_write(): with patch('child.Parent', MockParent): # 重新加载child模块,让Child继承MockParent importlib.reload(child) child_obj = child.Child() child_obj.write() # 编写断言逻辑
如果用unittest框架,也可以在测试类中用@patch装饰器,同样需要重新导入Child。
方案3:直接mock父类的write方法
如果不需要完整的MockParent类,直接mock Parent的write方法更轻量:
from unittest.mock import patch from child import Child def test_child_write(): with patch('parent.Parent.write') as mock_write: child = Child() child.write() # 断言父类方法被调用 mock_write.assert_called_once() # 还可以添加子类业务逻辑的验证步骤
内容的提问来源于stack exchange,提问作者david
相关产品推荐
相关产品推荐

