unittest 模拟和多重继承:TypeError:元类冲突

Posted

技术标签:

【中文标题】unittest 模拟和多重继承:TypeError:元类冲突【英文标题】:unittest mock and multiple inheritance: TypeError: metaclass conflict 【发布时间】:2018-06-06 09:32:57 【问题描述】:

我有一个包,它的依赖项不是pip 可安装的。为了能够构建文档,我正在尝试使用MagicMock 模拟不可安装的包。

但是我偶然发现了多重继承的问题:当其中一个父类是模拟类时,我得到:

TypeError:元类冲突:派生类的元类必须是元类的(非严格)子类

下面的例子说明了这个问题:

文件:class_a.py

class A:
    pass

文件:code.py

from class_a import A

class B:
    pass

class C(A, B):
    pass

文件:test.py

import sys
from unittest import mock

# inspired by https://***.com/a/37363830/1860757
MOCK_MODULES = ['class_a', ]
sys.modules.update((mod_name, mock.MagicMock()) for mod_name in MOCK_MODULES)

import code

code.C()

如果我运行python3 test.py,我会得到上述异常。 如果我注释以sys.modules.update 开头的行,则一切正常。

有没有办法模拟模块或类以使多重继承继续工作?

【问题讨论】:

【参考方案1】:

我做了更多的研究和测试,我找到了一种方法,所以为了完整性,我回答了我自己的问题。我不知道这是解决方案还是解决方法。然而,诀窍是显式模拟涉及多重继承的类。以下确实按预期工作:

import sys
from unittest import mock


class _A:
    pass

MOCK_MODULES = ['class_a', ]
sys.modules.update((mod_name, mock.MagicMock()) for mod_name in MOCK_MODULES)
patcher = mock.patch('class_a.A', new=_A)
patcher.start()


import code


code.C()

patcher.stop()

如果将来有人找到新的/更好的方法,请联系我,我将重新评估接受的答案。

【讨论】:

【参考方案2】:

我知道这是旧帖子,但无论如何。 看起来这些行不是必需的,因为模块 class_a 存在,您不需要模拟它:

# MOCK_MODULES = ['class_a', ]
# sys.modules.update((mod_name, mock.MagicMock()) for mod_name in MOCK_MODULES)

【讨论】:

以上是关于unittest 模拟和多重继承:TypeError:元类冲突的主要内容,如果未能解决你的问题,请参考以下文章

定义接口并模拟一个硬盘的功能包括接口实现多重继承

C++ 中的多重继承导致难以覆盖通用功能

多继承 与 多重继承

什么是多重继承,单重继承?

java中的多重继承是啥意思?

ts 类的变量、方法、实例化、继承、实现接口、抽象类