如何使用 MagicMock 欺骗 issubclass 检查?

问题描述 投票:0回答:1

我有这样的东西:

from unittest.mock import MagicMock

class A:
    pass

class B(A):
    pass

mock_B = MagicMock(spec_set=B)
assert issubclass(mock_B, A)  # TypeError: issubclass() arg 1 must be a class

我怎样才能让这个通过?

isinstance 和 Mocking 有很多不同的答案,但从那里我无法弄清楚。

python unit-testing subclass python-unittest.mock
1个回答
0
投票

这里的问题是,你想将

MagicMock
的实例视为类,但 Python 中的对象只有当它是
type
的实例时才能被视为实际的类。

一种解决方法是创建一个与要模拟的类具有相同基类的类,但通过使用定义了

__getattribute__
方法的元类创建该类,将其所有属性查找委托给模拟对象。但是,生成的“类”的行为不会像类,因为所有属性查找现在委托给的模拟对象没有类似类的属性。因此,我们可以通过将模拟对象中不可用的属性默认为被模拟的类来使其表现得更像一个类:

from unittest.mock import MagicMock

def mock_class(cls):
    class meta_mocked_class(type):
        def __getattribute__(self, name):
            try:
                return getattr(mock, name)
            except AttributeError:
                return getattr(cls, name)

    mock = MagicMock(spec_set=cls)
    return meta_mocked_class(cls.__name__, cls.__bases__, {})

这样:

class A:
    pass

class B(A):
    def foo(self):
        pass

mock_B = mock_class(B)
assert issubclass(mock_B, A)
print(mock_B)
print(mock_B.foo)
print(mock_B.__name__)
print(mock_B.__bases__)

通过

issubclass
断言并输出:

<class '__main__.B'>
<MagicMock name='mock.foo' id='1970990059024'>
B
(<class '__main__.A'>,)

演示:在线试用!

© www.soinside.com 2019 - 2024. All rights reserved.