Я попробовал приведенный ниже код, используя new_callable=PropertyMock для имитации вызова свойства и autospec=True для доступа к себе в функции побочного эффекта:
from unittest.mock import PropertyMock
def some_property_mock(self):
if self.__some_member == "some_value"
return "some_different_value"
else:
return "some_other_value"
mocker.patch.object(
SomeClass, "some_property", new_callable=PropertyMock, autospec=True, side_effect=some_property_mock)
Он выдает следующее исключение: ValueError: невозможно использовать «autospec» и «new_callable» вместе
Есть ли альтернатива достижению ожидаемого поведения?
Редактировать: Я попробовал решение, представленное в этом посте https://stackoverflow.com/a/77940234/7217960, но, похоже, оно не работает с PropertyMock. Результат печати дает MyMock name='my_property()' id='136687332325264' вместо 2, как ожидалось.
from unittest import mock
class MyClass(object):
def __int__(self):
self.my_attribute = 10
@property
def my_property(self):
return self.my_attribute + 1
def unit_under_test():
inst = MyClass()
return inst.my_property
class MyMock(mock.PropertyMock):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
print("MyMock __init__ called.")
with mock.patch.object(mock, 'MagicMock', MyMock):
with mock.patch.object(MyClass, 'my_property', autospec=True, side_effect=lambda self: 2) as spy:
result = unit_under_test()
assert result == 2
assert spy.call_count == 1
Обратите внимание, что этот вопрос является дубликатом вопроса Использование опции автоспецификации макета Mock.patch с пользовательским подклассом Mock
@blhsing Решение, приведенное в упомянутом вами сообщении, похоже, не работает с PropertyMock.






Поскольку свойство some_property исправлено с помощью MagicMock, а затем исправлено с помощью MyMock, и вы хотите установить возвращаемое значение свойства, вызываемого при его вызове, вам следует сделать это для фиктивного объекта, возвращенного после исправления MagicMock с помощью MyMock:
with mock.patch.object(mock, 'MagicMock', MyMock) as property_mock:
with mock.patch.object(MyClass, 'my_property', autospec=True) as spy:
property_mock.side_effect = lambda self: 2
# or property_mock.return_value = 2
result = unit_under_test()
assert result == 2
assert spy.call_count == 1
Если это свойство, то вам все равно нужен autospec=True? Я думаю, что для методов важно гарантировать правильность используемой подписи.