2

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

4

1 回答 1

4

您可以在 bmodule 本身中对其进行修补,而不是monkeypatching openin 。__builtins__这样做的好处是只有 bmodule 中的函数才能获得修补后的打开函数。您可以在模拟文档中看到更多详细信息。

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 块时补丁将被删除。需要该create=True部分来说服您确实打算open在命名空间中创建绑定的补丁bmodule- 这是一种安全预防措施,可防止人们意外地嘲笑错误的名称,但在您的情况下,它是必需的,因为 open 存在__builtins__但您想绑定它在bmodule.

于 2013-03-22T15:42:38.903 回答