mocking a parent class
<p>I have a <code>Parent</code> class that is inherited by a lot of <code>ChildX</code> classes.</p>

<pre><code>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
</code></pre>

<p>I have a test suite to run with pytest, and I want to make sure that, during these tests, everytime a <code>ChildX</code> is instanciated, the instance would call <code>MockParent</code>'s methods instead of the <code>Parent</code>'s ones (I simplified a lot the example above, the <code>__init__</code> method is not the only one concerned).</p>

<p>For the moment, all I've managed to do was to patch every <code>ChildX</code> class one by one:</p>

<pre><code>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
</code></pre>

<p>But I have many <code>ChildX</code> classes and sometimes <code>ChildY</code> is instanciated and used inside a method of <code>ChildZ</code>, so I can't patch them all.</p>

<p>I've tried many things to replace <code>Parent</code> by <code>MockParent</code>, but none of them worked. Here are some of my failed attempts:</p>

<pre><code>@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
</code></pre>

<p>Is this even possible? I'm using python2.7 and the up-to-date versions of <code>pytest</code> and <code>mock</code>.</p>

<p>No, it's not possible. The definitions of Child1 and Parent - including the inheritance of one from the other - are executed as soon as the module they are in is imported. There is no opportunity to get in before that and change the inheritance hierarchy.</p>

<p>The best you could do would be to move the definitions to some kind of factory function, which could dynamically define the parent of Child1 depending on what it was called with. </p>

python mocking py.test