[英]Mocking “with open()”
我正在尝试对从文件中读取行并对其进行处理的方法进行单元测试。
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:
最好的祝福
mock_open
的返回值(直到Python 3.7.1)没有提供有效的__iter__
方法,这可能使其不适合测试迭代打开文件对象的代码。
相反,我建议将代码重构为采用已打开的类似文件的对象。 也就是说,代替
def some_method(file_name):
with open([file_name], 'r') as file_list:
for line in file_list:
# Do stuff
...
some_method(file_name)
写成
def some_method(file_obj):
for line in file_obj:
# Do stuff
...
with open(file_name, 'r') as file_obj:
some_method(file_obj)
这将必须执行IO的功能转换为pure(r)函数,该函数可以简单地遍历任何类似于文件的对象。 要测试它,您无需以任何方式模拟open
或访问文件系统; 只需创建一个StringIO
对象用作参数即可:
def test_it(self):
f = StringIO.StringIO("line1\nline2\n")
some_method(f)
(如果您仍然需要编写和测试类似
def some_wrapper(file_name):
with open(file_name, 'r') as file_obj:
some_method(file_obj)
请注意,您不需要进行模拟打开就可以做任何特别的事情。 您需要分别测试some_method
,因此测试some_wrapper
唯一需要做的就是验证open
的返回值是否传递给some_method
。 在这种情况下, open
可以是没有任何特殊行为的普通旧模拟。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.