【发布时间】:2018-10-31 13:02:55
【问题描述】:
我正在尝试对一种从文件中读取行并进行处理的方法进行单元测试。
with open([file_name], 'r') as file_list:
for line in file_list:
# Do stuff
我尝试了其他问题中描述的几种方法,但似乎没有一种方法适用于这种情况。我不太明白python如何将文件对象用作行上的可迭代对象,它在内部使用 file_list.readlines() ?
这种方法行不通:
with mock.patch('[module_name].open') as mocked_open: # also tried with __builtin__ instead of module_name
mocked_open.return_value = 'line1\nline2'
我有一个
AttributeError: __exit__
也许是因为 with 语句有这个特殊的属性来关闭文件?
此代码使 file_list 成为 MagicMock。如何在此 MagicMock 上存储数据以对其进行迭代?
with mock.patch("__builtin__.open", mock.mock_open(read_data="data")) as mock_file:
最好的问候
【问题讨论】:
-
短语
for x in y:通过调用iter(y)创建一个迭代器,它将尝试调用y.__iter__()来创建它。所以我建议通过一个模拟来拦截这个调用。 -
read_data是您将迭代的数据。 -
这可能是您想要修改代码以使其更易于测试的情况。假设这是一个将文件名作为参数的函数,则改为使用文件 object。这使得调用者负责打开文件,但它也允许您传递
StringIO对象作为测试参数。 (作为一般规则,将 I/O 尽可能推到代码的边缘会更容易测试。) -
@chepner 我认为 read_data 仅适用于 file_obj.read() 方法,使用此方法让我找回了 read_data。因为在这段代码中它永远不会进入 for 循环,可能是因为它试图遍历 MagicMock 并且它不起作用。
-
查看
mock_open的文档,似乎直到 Python 3.7 才添加对__iter__的支持。 (这对我来说似乎是一个巨大的疏忽,但我猜,迟到总比没有好。)
标签: python python-2.7 mocking with-statement