I'm trying to mock an object that makes some expensive network calls when it's initialized, but the parent class instantiating it isn't recognizing the patch from my unit test.
Some similar questions I've already looked at:
- 1 Doesn't involve any inheritance like in my current situation.
 - 2 Has a similar inheritance structure, but it mocks a method instead of a constructor.
 
Minimal Reproducible Example 3
File Structure
--src
   |-- resource.py
   |-- family.py
   |-- test_child.py
resource.py
class Resource:
    def __init__(self):
        print("Expensive network call")
    def use_resource(self) -> str:
        print("Another expensive network call")
        return "bar"
family.py
from resource import Resource
class Parent:
    def __init__(self):
        print("In the Parent constructor.")
        self.resource = Resource()
    def foo(self):
        print("Parent's foo")
        print(self.resource.use_resource())
class Child(Parent):
    def __init__(self):
        super().__init__()
        print("In the Child constructor")
    
    def foo(self):
        print("Child's foo")
        super().foo()
test_child.py
import unittest
from unittest.mock import patch
from family import Child
class TestChild(unittest.TestCase):
    @patch('resource.Resource')
    def test_foo(self, mock_resource):
        mock_resource.return_value.use_resource.return_value = "mock_bar"
        child = Child()
        child.foo()
        mock_resource.return_value.use_resource.assert_called_once()
unittest.main()
Expected Result
Since I'm patching resource.Resource, I'm expecting to avoid the expensive network calls that normally occur when a Parent instantiates a Resource. Theoretically the output of running test_child.py should look like this:
In the Parent constructor.
In the Child constructor
Child's foo
Parent's foo
mock_bar
Actual Result
However, despite patching resource.Resource in the test, the Parent is still instantiating an actual Resource as evidenced by the presence of the "Expensive network call" messages in the output and the failed assert_called_once assertion.
In the Parent constructor.
Expensive network call           # Should have been patched
In the Child constructor
Child's foo
Parent's foo
Another expensive network call   # Should have been patched
bar                              # Should have been patched
F
======================================================================
FAIL: test_foo (__main__.TestChild)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "[REMOVED]\unittest\mock.py", line 1342, in patched
    return func(*newargs, **newkeywargs)
  File "[REMOVED]\test_child.py", line 13, in test_foo
    mock_resource.return_value.use_resource.assert_called_once()
  File "[REMOVED]\unittest\mock.py", line 886, in assert_called_once
    raise AssertionError(msg)
AssertionError: Expected 'use_resource' to have been called once. Called 0 times.
----------------------------------------------------------------------
Ran 1 test in 0.005s