Search code examples
pythonunit-testingmocking

Attribute error in child class for attribute defined in parent __init__ method


I have the following structure:

class Flop_helper(): 
    def __init__(...): 
        self.flop1 = [...]

class AnalyseMyHandFlop(Flop_helper): 
    def __init__(...): 
        self.flop1_nums = [card[0] for card in self.flop1]

class AnalyseMyHandTurn(AnalyseMyHandTurn): 
    ....

My unit test:

@mock.patch('some_path.FlopHelper')
@mock.patch('some_path.AnalyseMyHandOnFlop')
def test_function(mock_AnalyseMyHandOnFlop, mockFlopHelper):
    amhot = AnalyseMyHandOnTurn(...)

When I run the above test, I get:

self.flop1_nums = [card[0] for card in self.flop1]
E       AttributeError: 'AnalyseMyHandOnTurn' object has no attribute 'flop1'

The error message is so extremely confusing to me for two reasons:

  1. AnalyseMyHandOnTurn doesn't have an attribute flop1??? But I guess since we are inheriting AnalyseMyHandFlop, I can see why this could be.

  2. Didn't I mock out AnalyseMyHandFlop? So I would expect all its attributes and everything related to its class to be mocked out?


Solution

  • When you inherit a class in Python you get all its attributes methods etc. you also inherited the __init__ method, but when you defined the AnalyseMyHandFlop class you also provided an __init__ method overriding the one in Flop_helper, so when creating a new instance of AnalyseMyHandFlop only the __init__ of AnalyseMyHandFlop is being called.

    to fix it you need also to call the __init__ method of the parent class (Flop_helper) you can do that by adding this line to your code:

    class AnalyseMyHandFlop(Flop_helper):
        def __init__(self):
            super().__init__() # new line
            self.flop1_nums = [card[0] for card in self.flop1]