模拟上下文管理器中使用的类

时间:2015-07-29 23:06:41

标签: python mocking python-unittest

我有一个模块方法,它使用带有提供迭代的Class的上下文管理器:

import module

def ReadLog(log_file):
  with module.LogReader(log_file) as reader:
    combined_list = []
    for record in reader:
      combined_list.append(record)
    return combined_list

在我的unittest中,我试图模拟module.LogReader,以便它生成我自己定义的记录。这是我到目前为止所处的位置:

import mock
import my_mod

@mock.patch.object(my_mod.module, 'LogReader')
def testReadLog(self, mock_logreader):
  filename = '/fake/file/name.log'
  my_mod.ReadLog(filename)

  # Verify that module.LogReader was called
  mock_logreader.assert_called_once_with(filename)

但到目前为止,我还没有能够让迭代产生记录。 LogReader类有__enter__, __exit__, __iter__, next个方法,我尝试过mock_logreader.return_value = '123',但这会导致错误消息AttributeError: __exit__

我在这里失去了什么酱?

1 个答案:

答案 0 :(得分:2)

在调用正在测试的函数之前,需要在要模拟的函数上设置return_value。请注意,在您未设置此项的任何内容中,它都会返回一个新的MagicMock。您可以通过在此新return_value上设置MagicMock来拦截此内容。

例如:

file = 'foo' 
mock = MagicMock()  # could be gotten through patch
mock(file).__enter__().__iter__.return_value = [1,2,3,4,5]

with mock(file) as reader:
    for x in reader:
        print(x)

请参阅Python data model了解魔术功能的工作原理。