如何修补'打开'来自使用Mock的导入模块

时间:2013-03-22 15:03:03

标签: python unit-testing mocking monkeypatching

我正在为我所拥有的模块编写一些单元测试。我需要修补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

执行此操作

1 个答案:

答案 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中绑定它。