python - 如何使用 Mock 从导入的模块修补 'open'

标签 python unit-testing mocking monkeypatching

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

相关文章:

python - 打印出矩阵中的值

python - 如何通过shell脚本编辑XML文件来更改所有数字,其中原始点除以1.3?

unit-testing - 是否有任何工具、包或框架可以使用 Markdown 编写单元和/或集成测试?

java - 如何断言字符串不为空

java - Mockito 测试框架

python - 是否有用于解析 AWS cron 字符串并将其转换为日历日期的 python 库?

python - 测试两个列表是否相等

unit-testing - 可重用的模拟与每个测试中的模拟

c++ - 如何在 C++ 中的普通类或单例类中对私有(private)方法/枚举类进行 GoogleTest

python - opencv类型错误: 'int' object is not iterable