简体   繁体   English

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

[英]Mocking a Class used within a Context Manager

I have a module method that uses a context manager with a Class that offers iteration: 我有一个使用上下文管理器和提供迭代的类的模块方法:

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

In my unittest, I'm trying to mock module.LogReader such that it produces records defined by myself. 在我的单元测试中,我试图模拟module.LogReader,以便它生成由我定义的记录。 This is where I'm at so far: 这是我到目前为止的位置:

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)

But I haven't been able to make the iteration produce records so far. 但是到目前为止,我还无法使迭代产生记录。 The LogReader class has __enter__, __exit__, __iter__, next methods, and I've tried doing mock_logreader.return_value = '123' for example but this results in the error message AttributeError: __exit__ . LogReader类具有__enter__, __exit__, __iter__, next方法,例如,我尝试进行了mock_logreader.return_value = '123' ,但这会导致错误消息AttributeError: __exit__

What sauce am I missing here? 我在这里想念什么酱?

You need to set return_value on the functions you want to mock, before you call the function you're testing. 在调用要测试的函数之前,需要在要模拟的函数上设置return_value Note that on anything where you haven't set this, it'll return a new MagicMock . 请注意,在任何未设置此项的地方,它将返回一个新的MagicMock You can intercept this by setting a return_value on this new MagicMock . 您可以通过在此新MagicMock上设置return_value来拦截它。

So for example: 因此,例如:

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)

See the Python data model for how the magic functions work. 有关魔术函数的工作方式,请参见Python数据模型

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM