gpt4 book ai didi

python - mock 父类

转载 作者:行者123 更新时间:2023-12-04 16:45:03 26 4
gpt4 key购买 nike

我有一个 Parent 类,它被许多 ChildX 类继承。

class Parent(object):  # the class that should be mocked
def __init__(self):
assert False # should never happen, because we're supposed to use the mock instead

class Child1(Parent):
def method_1(self):
return 3

class MockParent(object): # this one should replace Parent
def __init__(self):
assert True

我有一个与 pytest 一起运行的测试套件,我想确保在这些测试期间,每次实例化 ChildX 时,该实例都会调用 MockParent的方法而不是 Parent 的方法(我简化了上面的示例,__init__ 方法不是唯一相关的方法)。

目前,我所能做的就是一个一个地修补每个 ChildX 类:

class FixturePatcher(object):
def __init__(self, klass):
self.klass = klass
self.patcher = None

def __enter__(self):
self.patcher = mock.patch.object(self.klass, '__bases__', (MockParent,))
return self.patcher.__enter__()

def __exit__(self, *_, **__):
self.patcher.is_local = True

@pytest.fixture()
def mock_parent_on_child1():
with FixturePatcher(Child1):
return Child1()

def test_mock_child1(mock_parent_on_child1):
assert mock_parent_on_child1.method_1() == 3

但我有很多 ChildX 类,有时 ChildY 被实例化并在 ChildZ 的方法中使用,所以我无法修补它们全部。

我已经尝试了很多方法来用 MockParent 替换 Parent,但是没有一个起作用。以下是我的一些失败尝试:

@mock.patch('src.parent.Parent', MockParent)
def test_mock_parent():
assert Child1().method_1() == 3 # Parent's __init__ method is still called

@mock.patch('src.parent.Parent.__getattribute__', lambda self, name: MockParent.__getattribute__(self, name))
def test_mock_parent():
assert Child1().method_1() == 3 # same results here

def test_mock_parent(monkeypatch):
monkeypatch.setattr('src.parent.Parent', MockParent)
assert Child1().method_1() == 3 # and still the same here

这可能吗?我正在使用 python2.7 和最新版本的 pytestmock

最佳答案

我想不出一种方法可以在所有使用它的地方用 MockParent 替换 Parent,但是你可以 monkeypatch Parent 的方法,如果那是你所追求的:

class Parent(object):
def my_method(self):
print 'my method'

class Child(Parent):
def run(self):
self.my_method()

child = Child()

child.run() # prints: my method

### Apply the monkeypatch: ###

def my_method(self):
print 'something else'

Parent.my_method = my_method

child.run() # prints: something else

您也可以使用 MockParent 中的方法对 Parent 的每个方法进行猴子修补,方法相同。这几乎与更改从 Parent 继承的所有内容的父类相同。

编辑:

事实上,如果您搜索 Parent 的所有现有子类,修补它们,如果 Parent 在它的模块,以便将来的类(class)也得到更新:

for child_class in Parent.__subclasses__():
mock.patch.object(child_class, '__bases__', (MockParent,))

parents_module.Parent = MockParent

我认为这仍然会遗漏一些特殊情况,因此对每个方法进行 monkeypatching 可能会更好。

关于python - mock 父类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39307257/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com