[英]Mock_open CSV file not getting any data
I am trying to unit test a piece of code: 我正在尝试对一段代码进行单元测试:
def _parse_results(self, file_name):
results_file = open(file_name)
results_data = list(csv.reader(results_file))
index = len(results_data[1])-1
results_file.close()
return float(results_data[1][index])
by using mock_open like so: 通过使用mock_open如此:
@mock.patch('path.open', mock.mock_open(read_data='test, test2, test3, test4'))
def test_parse_results(self):
cut = my_class(emulate=True)
self.assertEqual(VAL, cut._parse_results('file'))
The problem I am running into is that I do not get any data when running csv.reader. 我遇到的问题是我在运行csv.reader时没有得到任何数据。 If I run results_file.readlines() I get 'test, test2, test3, test4' which means that mock_open is working properly.
如果我运行results_file.readlines(),我得到'test,test2,test3,test4',这意味着mock_open正常工作。 But when I run csv.reader(results_file) I lose all the data.
但是当我运行csv.reader(results_file)时,我丢失了所有数据。
This is because mock_open
doesn't implement every feature that a file has, and notably not some of the ones that csv
needs. 这是因为
mock_open
没有实现文件所具有的每个功能,特别是csv
需要的功能。
mock_open
implements the methods read()
, readline()
and readlines()
, and works both as a function and when called as a context manager ( https://docs.python.org/3/library/unittest.mock.html#mock-open ), whereas csv.reader
works with… mock_open
实现方法read()
, readline()
和readlines()
,并且作为函数和作为上下文管理器调用时都可以工作( https://docs.python.org/3/library/unittest.mock.html#模拟打开 ),而csv.reader
使用...
any object which supports the iterator protocol and returns a string each time its
__next__()
method is called — file objects and list objects are both suitable任何支持迭代器协议的对象,每次调用
__next__()
方法时返回一个字符串 - 文件对象和列表对象都适用— https://docs.python.org/3/library/csv.html#csv.reader
- https://docs.python.org/3/library/csv.html#csv.reader
Note that mock_open
doesn't implement the __next__()
method, and doesn't raise StopIteration
when the end is reached, so it won't work with csv.reader
. 请注意,
mock_open
不实现__next__()
方法,并且在到达结尾时不会引发StopIteration
,因此它不适用于csv.reader
。
The solution, as @Emily points out in her answer, is to turn the file into a list of its lines. 正如@Emily在她的回答中指出的那样,解决方案是将文件转换为其行列表。 This is possible because
mock_open
implements readlines()
, and the resulting list is suitable for reading into csv.reader
as the documentation says. 这是可能的,因为
mock_open
实现readlines()
并将得到的名单适用于读取到csv.reader
的文件说。
This really got me too, and was a nightmare to pinpoint. 这真的让我受益匪浅,并且是一场噩梦。 To use your example code, this works
要使用您的示例代码,这是有效的
results_data = list(csv.reader(results_file.read()))
and this works 这很有效
results_data = list(csv.reader(results_file.readlines()))
but this doesn't work 但这不起作用
results_data = list(csv.reader(results_file))
using Python 3.4. 使用Python 3.4。
It seems counter to the documented interface of csv.reader
so maybe an expert can elaborate on why. 这似乎与
csv.reader
的文档化界面csv.reader
所以也许专家可以详细说明原因。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.