我有一个扩展unittest.testcase的基类,我想修补这个基类,这样扩展这个基类的类也将应用修补程序。
代码示例:
@patch("some.core.function", mocked_method)
class BaseTest(unittest.TestCase):
#methods
pass
class TestFunctions(BaseTest):
#methods
pass
直接修补
TestFunctions
类是有效的,但是修补basetest类不会改变some.core.function
中的功能。 最佳答案
这里可能需要一个元类:元类只定义了类的创建方式。
默认情况下,所有类都是使用python的内置类创建的。
>>> class Foo:
... pass
...
>>> type(Foo)
<class 'type'>
>>> isinstance(Foo, type)
True
所以类实际上是
type
的实例。现在,我们可以子类
type
来创建自定义元类(创建类的类):class PatchMeta(type):
"""A metaclass to patch all inherited classes."""
我们需要控制类的创建,所以我们要重写这里的
type
并在所有新实例上使用type.__new__
修饰器:class PatchMeta(type):
"""A metaclass to patch all inherited classes."""
def __new__(meta, name, bases, attrs):
cls = type.__new__(meta, name, bases, attrs)
cls = patch("some.core.function", mocked_method)(cls)
return cls
现在只需使用以下命令设置元类:
class BaseTest(unittest.TestCase):
__metaclass__ = PatchMeta
# methods
问题是这一行:
cls = patch("some.core.function", mocked_method)(cls)
所以现在我们总是用参数来修饰。
相反,您可以使它使用类的属性,例如:
cls = patch(*cls.patch_args)(cls)
然后将
patch
添加到类中:class BaseTest(unittest.TestCase):
__metaclass__ = PatchMeta
patch_args = ("some.core.function", mocked_method)
编辑:正如注释中提到的@mgilson,在适当的位置修改类的方法,而不是返回新的类。因此,我们可以将
__metaclass__ = PatchMeta
替换为"some.core.function"
:class PatchMeta(type):
"""A metaclass to patch all inherited classes."""
def __init__(cls, *args, **kwargs):
super(PatchMeta, self).__init__(*args, **kwargs)
patch(*cls.patch_args)(cls)
它绝对是干净的。
关于python - 继承一个修补过的类,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32981141/