Python Mock在一个类中修补多个方法

2024-04-26 22:06:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图修补一个类中的多个方法。这是我的简化设置

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方法。以下工作即打印新的密钥和新的值

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()

从直觉上看,第二个似乎也应该起作用,但没有。你能解释一下为什么没有。我怀疑这与"where to patch"有关,但我无法搞清楚。


Tags: keyfromimportselfgetreturnvaluedef
2条回答

你需要的是:

嘲笑班级挂钩

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_hook参数将其传递给test_execute2函数。让我们称之为mock1。mock1替换HookTransfer.py中的Hook类。当运行self.hook = Hook()时,它转换为调用mock1的__init__。按设计,这将返回另一个模拟实例-让我们将其称为mock2。所以self.hook指向mock2。但是mock_hook.get_key = mock.Mock(return_value="New_Key"),模拟mock1中的方法。

为了正确模拟,需要修补mock2。这有两种方法

  1. 通过模拟mock1的返回值(返回mock2)mock_hook.return_value.get_key = mock.Mock(return_value="New_Key")
  2. 模拟mock1(返回mock2)的构造函数的返回值mock_hook().get_key = mock.Mock(return_value="New_Key")

两个选项实际上做了同样的事情。

相关问题 更多 >