有没有办法在Python中模拟对象的isinstance()?

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

我想为库对象编写一个模拟而不继承它以便正确测试,但不必存根原始对象的所有未使用的函数。

具体来说,我想为调用库编写一个ContextMock。

class ContextMock:
    ...

这里的主要问题是我因此调用一个 @task 函数,然后该函数调用我想要测试的代码。然而 @task 装饰器检查上下文对象是否是 Context 的实例,如下所示:

def __call__(self, *args, **kwargs):
    # Guard against calling tasks with no context.
    if not isinstance(args[0], Context):
        err = "Task expected a Context as its first arg, got {} instead!"
        # TODO: raise a custom subclass _of_ TypeError instead
        raise TypeError(err.format(type(args[0])))

因此我的问题是,我能否以某种方式更改 ContextMock 的 isinstance 函数,或者使其看起来像 Context 的实例而不继承其属性? 或者是否可以以某种方式模拟 isinstance 函数? instancecheck 的默认实现是如何工作的?是否有一个可以被覆盖的基类属性?

我已经尝试提供一个带有自定义 instancecheck 函数的自定义元类,这当然不起作用,因为调用了 Context 的 instancecheck,对吧?

另请注意,我很清楚任何黑客解决方案都不应该属于生产代码,并且仅用于测试。

编辑: 添加我想要存档的通用示例:

class Context:
    pass

class ContextMock: 
    pass

mock = ContextMock

... do magic with mock

assert isinstance(mock, Context)
python inheritance mocking invoke isinstance
1个回答
0
投票

您只需提供

spec_set
spec
unittest.mock.Mock
即可实现此目的。示例

>>> class Context:
        pass
    
>>> mock = Mock(spec_set=Context)
>>> isinstance(mock, Context)
True

如果您需要使

mock
返回某些方法的某些特定值,您可以使用
mock.somemethod.return_value = someval

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