I am attempting to write a test for a function which calls an object’s classmethod — this classmethod goes on to return a new instance of that class.
There are plenty of examples of patching class attributes both here on stackoverflow and elsewhere but I am having difficulty understanding how to patch attribute/value such that I can test my function. I’ve referred to this answer.
Essentially I am trying to patch the attribute xxxx
of the instance of Foo (within myFn) so that I can test/assert the subsequent value from its call to some_other_function()
The code below is standalone a ‘runnable’ of the problem: I’m getting an AttributeError: Foo doesn’t have the attribute ‘xxxx’
import time import unittest from unittest.mock import patch, PropertyMock class Foo(object): def __init__(self, xxxx): """long running task""" time.sleep(5) self.xxxx = xxxx @classmethod def get(cls): """also a long running task""" time.sleep(5) xxxx = 555 return cls(xxxx) def myFn(): v = Foo.get().xxxx # the patched `xxxx` should be 666 at this point return some_other_function(v) class Test(unittest.TestCase): @patch('__main__.Foo', autospec=True) def test_myFn(self, mock_Foo): with patch('__main__.Foo.xxxx', new_callable=PropertyMock, return_value=666): x = myFn() self.assertEqual(x, 666) if __name__ == '__main__': unittest.main()
Very grateful for anyone’s help!
Advertisement
Answer
You should use the create
parameter that will force the creation of the attribute if it does not exist:
def test_myFn(self): with patch('__main__.xxxx', new_callable=PropertyMock, create=True, return_value=666): x = myFn() self.assertEqual(666,x)