[英]Python Mock Patch multiple methods in a class
我試圖修補一個類中的多個方法。 這是我的簡化設置
Hook.py 定義為
class Hook():
def get_key(self):
return "Key"
def get_value(self):
return "Value"
HookTransfer.py 定義為
from Hook import Hook
class HookTransfer():
def execute(self):
self.hook = Hook()
key = self.hook.get_key()
value = self.hook.get_value()
print(key)
print(value)
我想模擬 Hook 類中的 get_key 和 get_value 方法。 以下作品即打印 New_Key 和 New_Value
from HookTransfer import HookTransfer
import unittest
from unittest import mock
class TestMock(unittest.TestCase):
@mock.patch('HookTransfer.Hook.get_key', return_value="New_Key")
@mock.patch('HookTransfer.Hook.get_value', return_value="New_Value")
def test_execute1(self, mock_get_key, mock_get_value):
HookTransfer().execute()
if __name__ == '__main__':
unittest.main()
然而這並沒有。 它打印<MagicMock name='Hook().get_key()' id='4317706896'>
和<MagicMock name='Hook().get_value()' id='4317826128'>
from HookTransfer import HookTransfer
import unittest
from unittest import mock
class TestMock(unittest.TestCase):
@mock.patch('HookTransfer.Hook', spec=True)
def test_execute2(self, mock_hook):
mock_hook.get_key = mock.Mock(return_value="New_Key")
mock_hook.get_value = mock.Mock(return_value="New_Value")
HookTransfer().execute()
if __name__ == '__main__':
unittest.main()
直覺上,似乎第二個也應該工作,但事實並非如此。 你能幫助解釋為什么它沒有。 我懷疑它與“在哪里修補”有關,但我無法弄清楚。
您可以使用patch.multiple()
修補模塊或類的多個方法。 這樣的事情應該適用於您的情況:
import unittest
from unittest.mock import MagicMock, patch
class TestMock(unittest.TestCase):
@patch.multiple('HookTransfer.Hook',
get_key=MagicMock(return_value='New_Key'),
get_value=MagicMock(return_value='New_Value'))
def test_execute1(self, **mocks):
HookTransfer().execute()
當patch.multiple()
作為裝飾器使用時,mocks通過關鍵字傳遞給被裝飾的函數,當它作為上下文管理器使用時返回一個字典。
你需要的是:
模擬 Hook 類,
from HookTransfer import HookTransfer
from Hook import Hook
import unittest
try:
import mock
except ImportError:
from unittest import mock
class TestMock(unittest.TestCase):
@mock.patch.object(Hook, 'get_key', return_value="New_Key")
@mock.patch.object(Hook, 'get_value', return_value="New_Value")
def test_execute1(self, mock_get_key, mock_get_value):
HookTransfer().execute()
if __name__ == "__main__":
unittest.main()
經過一些測試,我能夠找到問題所在。
在第二個測試用例中,補丁裝飾器創建一個 Mock 類的新實例,並通過 mock_hook 參數將其傳遞給 test_execute2 函數。 讓我們將其稱為 mock1。 mock1 替換了 HookTransfer.py 中的 Hook 類。 當self.hook = Hook()
運行時,它轉換為調用 mock1 的__init__
。 按照設計,這會返回另一個 Mock 實例 - 讓我們將其稱為 mock2。 所以self.hook指向mock2。 但是mock_hook.get_key = mock.Mock(return_value="New_Key")
,mock1 中的方法。
為了正確模擬,mock2 需要打補丁。 這可以通過兩種方式完成
mock_hook.return_value.get_key = mock.Mock(return_value="New_Key")
mock_hook().get_key = mock.Mock(return_value="New_Key")
在幕后,這兩個選項確實做同樣的事情。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.