0

I'm trying to patch a function which I'm not directly importing but it is being used by the object under test. The patch is failing

My hierarchy structure looks like this

--src
   |--a
   |  |--b 
   |     |-- parent.py
   |
   |--c
      |--d
         |--e
            |-child.py
--test
   |--test_child.py

child.py looks like

class ChildClass(ParentClass):

    def child_method(self):
        // do stuff - which needs to be tested
        return self.parent_method()

parent.py looks like

from other_module import cool_function

class ParentClass:

    attribute x = cool_function()

    def parent_method():
        print(x)

In my test I'm trying to test the child_method() of the ChildClass, with a mocked value of attribute X. For doing so I'm mocking the cool_function() which I imported. I'm doing it like this

test_child.py

from mock import patch
from c.d.e.child import ChildClass

@patch(a.b.c.cool_function) #Mocked cool_function()
def test_child_function(mock_cool_function):
    mock_cool_function.return_value = Y # Mocked return value
    child_obj = ChildClass()
    child_obj.child_function()
    assert child_ojb.x == Y  # ===> Fails. Returns value by executing cool_function()
    //other asserts 

Wanted to know what's going wrong here. I followed this guide - Using python's mock patch.object to change the return value of a method called within another method

10gic_b0mb
  • 23
  • 4

1 Answers1

0

Ok, I'm taking a guess at what you want to achieve. I assume that your parent and child classes look something like this:

from other_module import cool_function

class ParentClass:
    x = cool_function()

    def parent_method(self):
        return self.x


class ChildClass(ParentClass):
    def child_method(self):
        return self.parent_method()

Then you want to replace the class variable by your own value.
In this case it doesn't help to replace cool_function, as the result is already assigned to x at load time, so patching it won't change x. Instead, you have to replace x itself in your test:

from mock import patch
import a
from c.d.e.child import ChildClass

@patch.object(a.b.parent.ParentClass, 'x', new='Y')
def test_child_function():
    child_obj = ChildClass()
    result = child_obj.child_method()
    assert result == 'Y'
MrBean Bremen
  • 14,916
  • 3
  • 26
  • 46