你如何模仿mock只讀屬性?如何用模擬模擬只讀屬性?
我想:
setattr(obj.__class__, 'property_to_be_mocked', mock.Mock())
但問題是,它則適用於類...打破我的測試中的所有實例。
你有什麼想法嗎?我不想嘲笑完整的對象,只有這個特定的屬性。
你如何模仿mock只讀屬性?如何用模擬模擬只讀屬性?
我想:
setattr(obj.__class__, 'property_to_be_mocked', mock.Mock())
但問題是,它則適用於類...打破我的測試中的所有實例。
你有什麼想法嗎?我不想嘲笑完整的對象,只有這個特定的屬性。
實際上,答案是(和往常一樣)在documentation中,只是當我按照他們的例子將補丁應用於實例而不是類時。
這裏是如何做到這一點:
class MyClass:
@property
def last_transaction(self):
# an expensive and complicated DB query here
pass
在測試套件:
def test():
# Make sure you patch on MyClass, not on a MyClass instance, otherwise
# you'll get an AttributeError, because mock is using settattr and
# last_transaction is a readonly property so there's no setter.
with mock.patch(MyClass, 'last_transaction') as mock_last_transaction:
mock_last_transaction.__get__ = mock.Mock(return_value=Transaction())
myclass = MyClass()
print myclass.last_transaction
我認爲更好的辦法是嘲笑財產PropertyMock
,而不是嘲笑__get__
方法直。
它在documentation中說明,搜索unittest.mock.PropertyMock
: 一個模擬打算用作一個類的屬性或其他描述符。 PropertyMock
提供了__get__
和__set__
方法,因此您可以在提取時指定返回值。
方法如下:
class MyClass:
@property
def last_transaction(self):
# an expensive and complicated DB query here
pass
def test(unittest.TestCase):
with mock.patch('MyClass.last_transaction', new_callable=PropertyMock) as mock_last_transaction:
mock_last_transaction.return_value = Transaction()
myclass = MyClass()
print myclass.last_transaction
mock_last_transaction.assert_called_once_with()
我不得不模擬一個以'@ property'裝飾的類方法。當其他答案(以及其他許多問題的其他答案)沒有答案時,這個答案對我有用。 – AlanSE 2016-05-19 20:32:04
這是它應該完成的方式。我希望有一種方法來移動「接受」的答案 – vitiral 2016-09-06 19:20:38
我發現包括上下文管理器調用中的返回值稍微更清晰: ''' with mock.patch('MyClass.last_transaction',new_callable = PropertyMock ,return_value = Transaction()): ... ''' – wodow 2017-06-30 17:38:02
大概的風格,但如果你喜歡裝飾在測試中,@ jamescastlefield的answer的事情可以改變的東西是這樣的:
class MyClass:
@property
def last_transaction(self):
# an expensive and complicated DB query here
pass
class Test(unittest.TestCase):
@mock.patch('MyClass.last_transaction', new_callable=PropertyMock)
def test(mock_last_transaction):
mock_last_transaction.return_value = Transaction()
myclass = MyClass()
print myclass.last_transaction
mock_last_transaction.assert_called_once_with()
如果你不您不想測試是否訪問了嘲弄的財產,您只需使用預期的return_value
即可對其進行修補。
with mock.patch(MyClass, 'last_transaction', Transaction()):
...
人應該用其他的例子。 'mock.PropertyMock'是實現它的方法! – vitiral 2016-09-06 19:21:02