如何在unmocked类中使用autospec修补classmethod?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在unmocked类中使用autospec修补classmethod?相关的知识,希望对你有一定的参考价值。

我想断言Python类中的一个类方法调用另一个带有一组参数的classmethod。我希望模拟的classmethod是“spec-ed”,因此它会检测是否使用错误的参数调用它。

当我使用patch.object(.., autospec=True, ..)修补classmethod时,classmethod被替换为NonCallableMagicMock并在我尝试调用它时引发错误。

from mock import patch

class A(object):

    @classmethod
    def api_meth(cls):
        return cls._internal_classmethod(1, 2, 3)

    @classmethod
    def _internal_classmethod(cls, n, m, o):
        return sum(n, m, o)

with patch.object(A, '_internal_classmethod') as p:
    print(type(p).__name__)

with patch.object(A, '_internal_classmethod', autospec=True) as p:
    print(type(p).__name__)

产生输出:

MagicMock
NonCallableMagicMock

如果_internal_classmethod所属的类没有被嘲笑,我怎样才能得到一个特定的模拟?

答案

有一个突出的错误报告(google code linkpython bug tracker link)来解决这个问题。在修复程序合并之前,你可以尝试下面这个对我有用[在2.7上,虽然我认为它也适用于3.x]。

def _patched_callable(obj):
    "Monkeypatch to allow autospec'ed classmethods and staticmethods."
    # See https://code.google.com/p/mock/issues/detail?id=241 and
    # http://bugs.python.org/issue23078 for the relevant bugs this
    # monkeypatch fixes
    if isinstance(obj, type):
        return True
    if getattr(obj, '__call__', None) is not None:
        return True
    if (isinstance(obj, (staticmethod, classmethod))
        and mock._callable(obj.__func__)):
        return True
    return False
_patched_callable._old_func = mock._callable
mock._callable = _patched_callable

在monkeypatch之后,你应该能够正常使用mock.patch并正确修补静态和类方法。

另一答案

使用spec代替autospec,并直接设置它。

with patch.object(A, '_internal_classmethod', spec=A._internal_classmethod) as p:
    print(type(p).__name__)

给我

MagicMock

输出。

以上是关于如何在unmocked类中使用autospec修补classmethod?的主要内容,如果未能解决你的问题,请参考以下文章

如何在python中修补常量

zookeeper漏洞如何修补?

Laravel框架 网站有漏洞如何修补与防护

如何修补已签名的 dll

如何使用装饰器修补sys属性?

如何使用 REST 从子文档数组中发布、修补和删除项目