【问题标题】:Getting an actual return value for a mocked file.read()获取模拟 file.read() 的实际返回值
【发布时间】:2012-01-05 17:08:43
【问题描述】:

我正在使用python-mock 模拟文件打开调用。我希望能够以这种方式传入假数据,这样我就可以验证 read() 是否被调用以及使用测试数据而不会在测试中访问文件系统。

这是我目前得到的:

file_mock = MagicMock(spec=file)
file_mock.read.return_value = 'test'

with patch('__builtin__.open', create=True) as mock_open:
    mock_open.return_value = file_mock

    with open('x') as f:
        print f.read()

我假设的输出是<mock.Mock object at 0x8f4aaec> 而不是'test'。我在构建这个模拟时做错了什么?

编辑:

看起来像这样:

with open('x') as f:
     f.read()

还有这个:

f = open('x')
f.read()

是不同的对象。使用模拟作为上下文管理器使它返回一个新的Mock,而直接调用它返回我在mock_open.return_value 中定义的任何内容。有什么想法吗?

【问题讨论】:

    标签: python tdd mocking python-mock


    【解决方案1】:

    在 Python 3 中,模式很简单:

    >>> import unittest.mock as um
    >>> with um.patch('builtins.open', um.mock_open(read_data='test')):
    ...     with open('/dev/null') as f:
    ...         print(f.read())
    ...
    test
    >>>
    

    (是的,您甚至可以模拟 /dev/null 以返回文件内容。)

    【讨论】:

      【解决方案2】:

      对于已经实现文件接口的StringIO 对象,这听起来像是一个很好的用例。也许你可以做一个file_mock = MagicMock(spec=file, wraps=StringIO('test'))。或者你可以让你的函数接受一个类似文件的对象并传递一个StringIO而不是一个真实的文件,避免需要丑陋的猴子补丁。

      你看过模拟文档吗?

      http://www.voidspace.org.uk/python/mock/compare.html#mocking-the-builtin-open-used-as-a-context-manager

      【讨论】:

      • 我试着用这个来解决一些问题。似乎 mock_open 在上下文管理器中使用时返回不同的对象,而不是直接调用。我已经更新了我的问题。有什么想法吗?
      • 我阅读了该页面的上半部分,但由于某种未知原因跳过了下半部分。 Herp 和 derp。
      • 如果该网站仍然是最新的,那将很有帮助。现在答案变得有点没用了。
      【解决方案3】:

      基于@tbc0 答案,支持 Python 2 和 3(多版本测试有助于端口 2 到 3):

      import sys
      module_ = "builtins"
      module_ = module_ if module_ in sys.modules else '__builtin__'
      
      try:
          import unittest.mock as mock
      except (ImportError,) as e:
          import mock 
      
      with mock.patch('%s.open' % module_, mock.mock_open(read_data='test')):
          with open('/dev/null') as f:
              print(f.read())
      

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-02
      相关资源
      最近更新 更多