Reputation: 21
When mocking a function, I can pass self
with autospec=True
:
def do_thing_side_effect(self):
pass
mocker.patch('module.class.do_thing', side_effect=do_thing_side_effect, autospec=True)
When mocking a property getter, I am unable to pass self
with either autospec=True
or spec=True
:
def thing_side_effect(self):
pass
mocker.patch('module.class.thing', new=mocker.PropertyMock(side_effect=thing_side_effect, autospec=True))
This yields:
Traceback (most recent call last):
File "/usr/local/lib/python3.9/unittest/mock.py", line 2848, in __get__
return self()
File "/usr/local/lib/python3.9/unittest/mock.py", line 1092, in __call__
return self._mock_call(*args, **kwargs)
File "/usr/local/lib/python3.9/unittest/mock.py", line 1096, in _mock_call
return self._execute_mock_call(*args, **kwargs)
File "/usr/local/lib/python3.9/unittest/mock.py", line 1157, in _execute_mock_call
result = effect(*args, **kwargs)
TypeError: thing_side_effect() missing 1 required positional argument: 'self'
Using spec
instead of autospec
causes the same error:
from module import class
def thing_side_effect(self):
pass
mocker.patch('module.class.thing', new=mocker.PropertyMock(side_effect=thing_side_effect, spec=class.thing))
Using spec
+ new_callable
instead of new
causes the same error:
from module import class
def thing_side_effect(self):
pass
mocker.patch('module.class.thing', spec=mocker.create_autospec(class.thing, side_effect=thing_side_effect, new_callable=mocker.PropertyMock)
Upvotes: 2
Views: 208
Reputation: 78923
By passing a class whose __get__
method does the side effect you want you can make this work, although I'm sure there's a more "built-in" to do it (but I haven't found what that is.)
from unittest.mock import patch, PropertyMock
class ThingSideEffect:
def __get__(self, instance, instance_class):
pass
patch('module.class.thing', new_callable=PropertyMock(side_effect=ThingSideEffect)))
That will drop you into __get__
when you request the property from your class instance.
Upvotes: 0
Reputation: 609
If i understand you correctly, in your case i think it would be best to use patch.object
with patch.object(module.class, 'thing_side_effect', new_callable=PropertyMock) as thing_side_effect_mock:
thing_side_effect_mock.side_effect = "what ever you want to return here"
Good luck :)
Upvotes: 2