Robert Speck
Robert Speck

Reputation: 3

Test if super() was called during initialization gives AttributeError

I would like to test if in the following scenario the init routine of the Base class is called during the initialization of the Derived class:

class Base(object):
    def __init__(self, a):
        self.a = a

class Derived(Base):
    def __init__(self, a):
        super(Derived, self).__init__(a)

I used this post here and this test works fine:

@mock.patch("mocktest.Base.__init__")
def test_calls_init_routine_of_base(mock_super_init):
    Derived(1)
    assert mock_super_init.called

However, if the Derived class does something with the attribute a after super(Derived, self).__init(a), e.g. if I put a print(self.a) right after the call to super(), then the test throws an AttributeError:

AttributeError: 'Derived' object has no attribute 'a'

How can I prevent this? Are there other/better ways to realize this test in this situation?

Upvotes: 0

Views: 580

Answers (1)

Michele d'Amico
Michele d'Amico

Reputation: 23721

Seriously, never do this kind of mock... If you want to test super call try to find a super behavior that you can check.

If you don't find any other way or you have some mysterious reasons to check it (I did it in the past but I cannot remember why... maybe I did the wrong thing) you can just wrap it:

@mock.patch("mocktest.Base.__init__", wraps=mocktest.Base.__init__)
def test_calls_init_routine_of_base(mock_super_init):
    Derived(1)
    assert mock_super_init.called

If you really need to avoid a super call (for instance you derive from something that start a thread or access to some remote resource) you should patch the attributes that you need too:

@mock.patch("mocktest.Base.a", create=True)
@mock.patch("mocktest.Base.__init__")
def test_calls_init_routine_of_base(mock_super_init):
    Derived(1)

Upvotes: 1

Related Questions