我正在为我拥有的模块编写一些单元测试。我需要修补 open
,以便当测试模块内的函数调用 open
时,使用模拟而不是真正的 open
。
这段代码可以工作,但我认为它会破坏另一个测试,因为没有将 open
恢复为其原始值:
class TestCases(unittest.TestCase):
def test_something(self):
from amodule import bmodule
open_mock = mock.MagicMock(spec=open)
bmodule.__builtins__['open'] = open_mock
read_mock = mock.MagicMock()
open_mock.return_value.__enter__.return_value = read_mock
self.assertTrue(bmodule.some_function())
self.assertEqual(open_mock.call_args_list, ['filename1', 'filename2'])
如何使用 mock.patch
执行此操作?
最佳答案
而不是猴子补丁open
在__builtins__
,您可以在 bmodule 本身中修补它。这样做的好处是只有 bmodule 中的函数才能获得修补后的 open 函数。
您可以在mock documentation中查看更多详细信息。 .
因此,您可以使用 patch.object
将您的 open 版本放在适当的位置作为上下文管理器:
from mock import patch
class TestCases(unittest.TestCase):
def test_something(self):
from amodule import bmodule
open_mock = mock.MagicMock(spec=open)
read_mock = mock.MagicMock()
open_mock.return_value.__enter__.return_value = read_mock
with patch.object(bmodule, 'open', open_mock, create=True):
self.assertTrue(bmodule.some_function())
self.assertEqual(open_mock.call_args_list, ['filename1', 'filename2'])
with 语句保证当执行离开 with block 时补丁将被删除。 create=True
需要部分来说服补丁您确实打算创建 open
绑定(bind)在 bmodule
命名空间 - 这是一项安全预防措施,可防止人们意外地 mock 错误的名称,但在您的情况下,这是必要的,因为 open 存在于 __builtins__
中。但你想将它绑定(bind)在 bmodule
.
关于python - 如何使用 Mock 从导入的模块修补 'open',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15573569/