[英]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.