我正在为我所拥有的模块编写一些单元测试。我需要修补open
所以当测试模块中的函数调用open
时,将使用mock而不是真实的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
?
答案 0 :(得分:4)
而不是在open
中对__builtins__
进行monkeypatching,你可以在bmodule中修补它。这样做的好处是只有bmodule中的函数才能获得修补程序的打开功能。
您可以在mock documentation。
因此,您可以使用patch.object
作为上下文管理器将您的开放版本放在适当位置:
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块时删除补丁。需要create=True
部分来说服您打算在open
命名空间中创建bmodule
绑定的补丁 - 这是一种安全预防措施,可以防止人们意外地模拟错误的名称,但是在你的情况下,它是必需的,因为__builtins__
中的开放生活,但你想在bmodule
中绑定它。